]> andersk Git - moira.git/blame - incremental/ldap/winad.c
*** empty log message ***
[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
0ea7f4a0 2580 if(!ActiveDirectory)
2581 {
2582 ADD_ATTR("name", name_v, LDAP_MOD_REPLACE);
2583 }
2584
61a2844b 2585 if (Exchange)
2586 {
2587 if(atoi(maillist) && !MailDisabled && email_isvalid(mail))
2588 {
2589 mail_nickname_v[0] = mail_nickname;
2590 proxy_address_v[0] = proxy_address;
2591 mail_v[0] = mail;
2592 report_to_originator_v[0] = "TRUE";
2593
2594 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
2595 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2596 ADD_ATTR("proxyAddresses", proxy_address_v, LDAP_MOD_REPLACE);
2597 ADD_ATTR("reportToOriginator", report_to_originator_v,
2598 LDAP_MOD_REPLACE);
2599 }
2600 else
2601 {
2602 mail_nickname_v[0] = NULL;
2603 proxy_address_v[0] = NULL;
2604 mail_v[0] = NULL;
2605 legacy_exchange_dn_v[0] = NULL;
2606 address_book_v[0] = NULL;
2607 report_to_originator_v[0] = NULL;
2608
2609 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
2610 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2611 ADD_ATTR("proxyAddresses", proxy_address_v, LDAP_MOD_REPLACE);
2612 ADD_ATTR("legacyExchangeDN", legacy_exchange_dn_v, LDAP_MOD_REPLACE);
2613 ADD_ATTR("showInAddressBook", address_book_v, LDAP_MOD_REPLACE);
2614 ADD_ATTR("reportToOriginator", report_to_originator_v,
2615 LDAP_MOD_REPLACE);
2616 }
2617 }
2618 else
2619 {
2620 if(atoi(maillist) && email_isvalid(contact_mail))
2621 {
2622 mail_v[0] = contact_mail;
2623 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
a0407f40 2624
2625 if(!ActiveDirectory)
2626 {
2627 null_v[0] = "/dev/null";
2628 ADD_ATTR("mailRoutingAddress", null_v, LDAP_MOD_REPLACE);
2629 }
61a2844b 2630 }
2631 }
2632
2633 mods[n] = NULL;
2634
2635 if ((rc = ldap_modify_s(ldap_handle, new_dn, mods)) != LDAP_SUCCESS)
2636 {
2637 com_err(whoami, 0,
2638 "Unable to modify list data for %s after renaming: %s",
2639 after_group_name, ldap_err2string(rc));
2640 }
2641
2642 for (i = 0; i < n; i++)
2643 free(mods[i]);
2644
2645 return(rc);
2646}
2647
2648int group_create(int ac, char **av, void *ptr)
2649{
2650 LDAPMod *mods[20];
2651 char new_dn[256];
2652 char group_ou[256];
2653 char new_group_name[256];
2654 char sam_group_name[256];
2655 char cn_group_name[256];
2656 char mail[256];
2657 char contact_mail[256];
2658 char mail_nickname[256];
2659 char proxy_address[256];
2660 char address_book[256];
2661 char *cn_v[] = {NULL, NULL};
2662 char *objectClass_v[] = {"top", "group", NULL};
2663 char *objectClass_ldap_v[] = {"top", "microsoftComTop", "securityPrincipal",
2664 "group", "mailRecipient", NULL};
2665 char info[256];
2666 char *samAccountName_v[] = {NULL, NULL};
2667 char *altSecurityIdentities_v[] = {NULL, NULL};
2668 char *member_v[] = {NULL, NULL};
2669 char *name_v[] = {NULL, NULL};
2670 char *desc_v[] = {NULL, NULL};
2671 char *info_v[] = {NULL, NULL};
2672 char *mitMoiraId_v[] = {NULL, NULL};
2673 char *mitMoiraPublic_v[] = {NULL, NULL};
2674 char *mitMoiraHidden_v[] = {NULL, NULL};
2675 char *groupTypeControl_v[] = {NULL, NULL};
2676 char *mail_v[] = {NULL, NULL};
2677 char *proxy_address_v[] = {NULL, NULL};
2678 char *mail_nickname_v[] = {NULL, NULL};
2679 char *report_to_originator_v[] = {NULL, NULL};
2680 char *address_book_v[] = {NULL, NULL};
2681 char *legacy_exchange_dn_v[] = {NULL, NULL};
2682 char *gidNumber_v[] = {NULL, NULL};
a0407f40 2683 char *null_v[] = {NULL, NULL};
61a2844b 2684 char groupTypeControlStr[80];
2685 char group_membership[1];
2686 int i;
2687 int security_flag;
2688 u_int groupTypeControl;
2689 int n;
2690 int rc;
2691 int updateGroup;
2692 int MailDisabled = 0;
2693 char **call_args;
2694 LK_ENTRY *group_base;
2695 int group_count;
2696 char filter[1024];
2697 char *attr_array[3];
2698
2699 call_args = ptr;
2700
2701 if(UseGroupUniversal)
2702 groupTypeControl = ADS_GROUP_TYPE_UNIVERSAL_GROUP;
2703 else
2704 groupTypeControl = ADS_GROUP_TYPE_GLOBAL_GROUP;
2705
2706 if (!check_string(av[L_NAME]))
2707 {
2708 com_err(whoami, 0, "Unable to process invalid LDAP list name %s",
2709 av[L_NAME]);
2710 return(AD_INVALID_NAME);
2711 }
2712
2713 updateGroup = (int)call_args[4];
2714 memset(group_ou, 0, sizeof(group_ou));
2715 memset(group_membership, 0, sizeof(group_membership));
2716 security_flag = 0;
2717
2718 get_group_membership(group_membership, group_ou, &security_flag, av);
2719
2720 strcpy(new_group_name, av[L_NAME]);
2721 sprintf(new_dn, "cn=%s,%s,%s", new_group_name, group_ou, call_args[1]);
2722 sprintf(contact_mail, "%s@mit.edu", av[L_NAME]);
2723 sprintf(mail, "%s@%s", av[L_NAME], lowercase(ldap_domain));
2724 sprintf(mail_nickname, "%s", av[L_NAME]);
2725
2726 if (security_flag)
2727 groupTypeControl |= ADS_GROUP_TYPE_SECURITY_ENABLED;
2728
2729 sprintf(sam_group_name, "%s%s", av[L_NAME], group_suffix);
2730
2731 if (!updateGroup)
2732 {
2733 sprintf(groupTypeControlStr, "%ld", groupTypeControl);
2734 groupTypeControl_v[0] = groupTypeControlStr;
2735
2736 strcpy(cn_group_name, av[L_NAME]);
2737
2738 samAccountName_v[0] = sam_group_name;
2739 name_v[0] = new_group_name;
2740 cn_v[0] = new_group_name;
2741
2742 n = 0;
2743 ADD_ATTR("cn", cn_v, LDAP_MOD_ADD);
2744
2745 if(ActiveDirectory)
2746 {
2747 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
2748 }
2749 else
2750 {
2751 mitMoiraPublic_v[0] = av[L_PUBLIC];
2752 mitMoiraHidden_v[0] = av[L_HIDDEN];
2753 ADD_ATTR("objectClass", objectClass_ldap_v, LDAP_MOD_ADD);
2754 ADD_ATTR("mitMoiraPublic", mitMoiraPublic_v, LDAP_MOD_ADD);
2755 ADD_ATTR("mitMoiraHidden", mitMoiraHidden_v, LDAP_MOD_ADD);
2756
2757 if(atoi(av[L_GROUP]))
2758 {
2759 gidNumber_v[0] = av[L_GID];
2760 ADD_ATTR("gidNumber", gidNumber_v, LDAP_MOD_ADD);
2761 }
2762 }
2763
2764 ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_ADD);
2765 ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
2766 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
2767
2768 if (Exchange)
2769 {
2770 if(atoi(av[L_MAILLIST]))
2771 {
2772 group_count = 0;
2773 group_base = NULL;
2774
2775 sprintf(filter, "(&(objectClass=user)(cn=%s))", av[L_NAME]);
2776 attr_array[0] = "cn";
2777 attr_array[1] = NULL;
2778
2779 if ((rc = linklist_build((LDAP *)call_args[0], call_args[1],
2780 filter, attr_array, &group_base,
2781 &group_count,
2782 LDAP_SCOPE_SUBTREE)) != 0)
2783 {
2784 com_err(whoami, 0, "Unable to process group %s : %s",
2785 av[L_NAME], ldap_err2string(rc));
2786 return(rc);
2787 }
2788
2789 if (group_count)
2790 {
2791 com_err(whoami, 0, "Object already exists with name %s",
2792 av[L_NAME]);
2793 MailDisabled++;
2794 }
2795
2796 linklist_free(group_base);
2797 group_base = NULL;
2798 group_count = 0;
2799 }
2800
2801 if(atoi(av[L_MAILLIST]) && !MailDisabled && email_isvalid(mail))
2802 {
2803 mail_nickname_v[0] = mail_nickname;
2804 report_to_originator_v[0] = "TRUE";
2805
2806 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_ADD);
2807 ADD_ATTR("reportToOriginator", report_to_originator_v,
2808 LDAP_MOD_ADD);
2809 }
2810 }
2811 else
2812 {
2813 if(atoi(av[L_MAILLIST]) && email_isvalid(contact_mail))
2814 {
2815 mail_v[0] = contact_mail;
2816 ADD_ATTR("mail", mail_v, LDAP_MOD_ADD);
a0407f40 2817
2818 if(!ActiveDirectory)
2819 {
2820 null_v[0] = "/dev/null";
2821 ADD_ATTR("mailRoutingAddress", null_v, LDAP_MOD_ADD);
2822 }
61a2844b 2823 }
2824 }
2825
2826 if (strlen(av[L_DESC]) != 0)
2827 {
2828 desc_v[0] = av[L_DESC];
2829 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
2830 }
2831
2832 ADD_ATTR("groupType", groupTypeControl_v, LDAP_MOD_ADD);
2833
2834 if (strlen(av[L_ACE_NAME]) != 0)
2835 {
2836 sprintf(info, "The Administrator of this list is: %s",
2837 av[L_ACE_NAME]);
2838 info_v[0] = info;
2839 ADD_ATTR("info", info_v, LDAP_MOD_ADD);
2840 }
2841
2842 if (strlen(call_args[5]) != 0)
2843 {
2844 mitMoiraId_v[0] = call_args[5];
2845 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_ADD);
2846 }
2847
2848 mods[n] = NULL;
2849
2850 rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL);
2851
2852 for (i = 0; i < n; i++)
2853 free(mods[i]);
2854
2855 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
2856 {
c9ef9269 2857 com_err(whoami, 0, "Unable to create list %s in directory : %s",
61a2844b 2858 av[L_NAME], ldap_err2string(rc));
2859 callback_rc = rc;
2860 return(rc);
2861 }
2862 }
2863
2864 if ((rc == LDAP_ALREADY_EXISTS) || (updateGroup))
2865 {
2866 rc = attribute_update((LDAP *)call_args[0], new_dn, av[L_DESC],
2867 "description", av[L_NAME]);
2868 sprintf(info, "The Administrator of this list is: %s", av[L_ACE_NAME]);
2869
2870 rc = attribute_update((LDAP *)call_args[0], new_dn, info, "info",
2871 av[L_NAME]);
2872
2873 n = 0;
2874
2875 if (strlen(call_args[5]) != 0)
2876 {
2877 mitMoiraId_v[0] = call_args[5];
2878 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_REPLACE);
2879 }
2880
2881 if (!(atoi(av[L_ACTIVE])))
2882 {
2883 member_v[0] = NULL;
2884 ADD_ATTR("member", member_v, LDAP_MOD_REPLACE);
2885 }
2886
2887 if (!ActiveDirectory)
2888 {
2889 mitMoiraPublic_v[0] = av[L_PUBLIC];
2890 mitMoiraHidden_v[0] = av[L_HIDDEN];
2891 ADD_ATTR("mitMoiraPublic", mitMoiraPublic_v, LDAP_MOD_REPLACE);
2892 ADD_ATTR("mitMoiraHidden", mitMoiraHidden_v, LDAP_MOD_REPLACE);
2893
2894 if(atoi(av[L_GROUP]))
2895 {
2896 gidNumber_v[0] = av[L_GID];
2897 ADD_ATTR("gidNumber", gidNumber_v, LDAP_MOD_REPLACE);
2898 }
2899 else
2900 {
2901 ADD_ATTR("gidNumber", gidNumber_v, LDAP_MOD_REPLACE);
2902 }
2903 }
2904
2905 if (Exchange)
2906 {
2907 if(atoi(av[L_MAILLIST]))
2908 {
2909 group_count = 0;
2910 group_base = NULL;
2911
2912 sprintf(filter, "(&(objectClass=user)(cn=%s))", av[L_NAME]);
2913 attr_array[0] = "cn";
2914 attr_array[1] = NULL;
2915
2916 if ((rc = linklist_build((LDAP *)call_args[0], call_args[1],
2917 filter, attr_array, &group_base,
2918 &group_count,
2919 LDAP_SCOPE_SUBTREE)) != 0)
2920 {
2921 com_err(whoami, 0, "Unable to process group %s : %s",
2922 av[L_NAME], ldap_err2string(rc));
2923 return(rc);
2924 }
2925
2926 if (group_count)
2927 {
2928 com_err(whoami, 0, "Object already exists with name %s",
2929 av[L_NAME]);
2930 MailDisabled++;
2931 }
2932
2933 linklist_free(group_base);
2934 group_base = NULL;
2935 group_count = 0;
2936 }
2937
2938 if (atoi(av[L_MAILLIST]) && !MailDisabled && email_isvalid(mail))
2939 {
2940 mail_nickname_v[0] = mail_nickname;
2941 report_to_originator_v[0] = "TRUE";
2942
2943 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
2944 ADD_ATTR("reportToOriginator", report_to_originator_v,
2945 LDAP_MOD_REPLACE);
2946 }
2947 else
2948 {
2949 mail_v[0] = NULL;
2950 mail_nickname_v[0] = NULL;
2951 proxy_address_v[0] = NULL;
2952 legacy_exchange_dn_v[0] = NULL;
2953 address_book_v[0] = NULL;
2954 report_to_originator_v[0] = NULL;
2955
2956 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
2957 ADD_ATTR("proxyAddresses", proxy_address_v, LDAP_MOD_REPLACE);
2958 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2959 ADD_ATTR("legacyExchangeDN", legacy_exchange_dn_v,
2960 LDAP_MOD_REPLACE);
2961 ADD_ATTR("showInAddressBook", address_book_v, LDAP_MOD_REPLACE);
2962 ADD_ATTR("reportToOriginator", report_to_originator_v,
2963 LDAP_MOD_REPLACE);
2964 }
2965 }
2966 else
2967 {
2968 if (atoi(av[L_MAILLIST]) && email_isvalid(contact_mail))
2969 {
2970 mail_v[0] = contact_mail;
2971 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
a0407f40 2972
2973 if(!ActiveDirectory)
2974 {
2975 null_v[0] = "/dev/null";
2976 ADD_ATTR("mailRoutingAddress", null_v, LDAP_MOD_REPLACE);
2977 }
61a2844b 2978 }
2979 else
2980 {
2981 mail_v[0] = NULL;
2982 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
a0407f40 2983
2984 if(!ActiveDirectory)
2985 {
2986 null_v[0] = NULL;
2987 ADD_ATTR("mailRoutingAddress", null_v, LDAP_MOD_REPLACE);
2988 }
61a2844b 2989 }
2990 }
2991
2992 mods[n] = NULL;
2993 rc = LDAP_SUCCESS;
2994
2995 if (n != 0)
2996 {
2997 rc = ldap_modify_s((LDAP *)call_args[0], new_dn, mods);
2998
2999 for (i = 0; i < n; i++)
3000 free(mods[i]);
3001
3002 if (rc != LDAP_SUCCESS)
3003 {
c9ef9269 3004 com_err(whoami, 0, "Unable to update list %s in directory : %s",
61a2844b 3005 av[L_NAME], ldap_err2string(rc));
3006 callback_rc = rc;
3007 return(rc);
3008 }
3009 }
3010 }
3011
3012 ProcessGroupSecurity((LDAP *)call_args[0], call_args[1], av[L_NAME],
3013 atoi(av[L_HIDDEN]), av[L_ACE_TYPE], av[L_ACE_NAME]);
3014
3015 return(LDAP_SUCCESS);
3016}
3017
3018int ProcessGroupSecurity(LDAP *ldap_handle, char *dn_path,
3019 char *TargetGroupName, int HiddenGroup,
3020 char *AceType, char *AceName)
3021{
3022 char filter_exp[1024];
3023 char *attr_array[5];
3024 char search_path[512];
3025 char root_ou[128];
3026 char TemplateDn[512];
3027 char TemplateSamName[128];
3028 char TargetDn[512];
3029 char TargetSamName[128];
3030 char AceSamAccountName[128];
3031 char AceDn[256];
3032 unsigned char AceSid[128];
3033 unsigned char UserTemplateSid[128];
3034 char acBERBuf[N_SD_BER_BYTES];
3035 char GroupSecurityTemplate[256];
3036 char hide_addres_lists[256];
3037 char address_book[256];
3038 char *hide_address_lists_v[] = {NULL, NULL};
3039 char *address_book_v[] = {NULL, NULL};
3040 char *owner_v[] = {NULL, NULL};
3041 int AceSidCount;
3042 int UserTemplateSidCount;
3043 int group_count;
3044 int n;
3045 int i;
3046 int rc;
3047 int nVal;
3048 ULONG dwInfo;
3049 int array_count = 0;
3050 LDAPMod *mods[20];
3051 LK_ENTRY *group_base;
3052 LDAP_BERVAL **ppsValues;
3053 LDAPControl sControl = {"1.2.840.113556.1.4.801",
3054 { N_SD_BER_BYTES, acBERBuf },
3055 TRUE
3056 };
3057 LDAPControl *apsServerControls[] = {&sControl, NULL};
3058 LDAPMessage *psMsg;
3059
3060 dwInfo = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
3061 DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION;
3062 BEREncodeSecurityBits(dwInfo, acBERBuf);
3063
3064 sprintf(search_path, "%s,%s", group_ou_root, dn_path);
3065 sprintf(filter_exp, "(sAMAccountName=%s%s)", TargetGroupName, group_suffix);
3066 attr_array[0] = "sAMAccountName";
3067 attr_array[1] = NULL;
3068 group_count = 0;
3069 group_base = NULL;
3070
3071 if ((rc = linklist_build(ldap_handle, search_path, filter_exp, attr_array,
3072 &group_base, &group_count,
3073 LDAP_SCOPE_SUBTREE) != 0))
3074 return(1);
3075
3076 if (group_count != 1)
3077 {
3078 linklist_free(group_base);
3079 return(1);
3080 }
3081
3082 strcpy(TargetDn, group_base->dn);
3083 strcpy(TargetSamName, group_base->value);
3084 linklist_free(group_base);
3085 group_base = NULL;
3086 group_count = 0;
3087
3088 UserTemplateSidCount = 0;
3089 memset(UserTemplateSid, '\0', sizeof(UserTemplateSid));
3090 memset(AceSamAccountName, '\0', sizeof(AceSamAccountName));
3091 memset(AceSid, '\0', sizeof(AceSid));
3092 AceSidCount = 0;
3093 group_base = NULL;
3094 group_count = 0;
3095
3096 if (strlen(AceName) != 0)
3097 {
3098 if (!strcmp(AceType, "LIST"))
3099 {
3100 sprintf(AceSamAccountName, "%s%s", AceName, group_suffix);
3101 strcpy(root_ou, group_ou_root);
3102 }
3103 else if (!strcmp(AceType, "USER"))
3104 {
3105 sprintf(AceSamAccountName, "%s", AceName);
3106 strcpy(root_ou, user_ou);
3107 }
3108
3109 if (ActiveDirectory)
3110 {
3111 if (strlen(AceSamAccountName) != 0)
3112 {
3113 sprintf(search_path, "%s", dn_path);
3114 sprintf(filter_exp, "(sAMAccountName=%s)", AceSamAccountName);
3115 attr_array[0] = "objectSid";
3116 attr_array[1] = NULL;
3117 group_count = 0;
3118 group_base = NULL;
3119
3120 if ((rc = linklist_build(ldap_handle, search_path, filter_exp,
3121 attr_array, &group_base, &group_count,
3122 LDAP_SCOPE_SUBTREE) != 0))
3123 return(1);
3124 if (group_count == 1)
3125 {
3126 strcpy(AceDn, group_base->dn);
3127 AceSidCount = group_base->length;
3128 memcpy(AceSid, group_base->value, AceSidCount);
3129 }
3130 linklist_free(group_base);
3131 group_base = NULL;
3132 group_count = 0;
3133 }
3134 }
3135 else
3136 {
3137 if (strlen(AceSamAccountName) != 0)
3138 {
3139 sprintf(search_path, "%s", dn_path);
3140 sprintf(filter_exp, "(sAMAccountName=%s)", AceSamAccountName);
3141 attr_array[0] = "samAccountName";
3142 attr_array[1] = NULL;
3143 group_count = 0;
3144 group_base = NULL;
3145
3146 if ((rc = linklist_build(ldap_handle, search_path, filter_exp,
3147 attr_array, &group_base, &group_count,
3148 LDAP_SCOPE_SUBTREE) != 0))
3149 return(1);
3150 if (group_count == 1)
3151 {
3152 strcpy(AceDn, group_base->dn);
3153 }
3154 linklist_free(group_base);
3155 group_base = NULL;
3156 group_count = 0;
3157 }
3158 }
3159 }
3160
3161 if (!ActiveDirectory)
3162 {
3163 if (strlen(AceDn) != 0)
3164 {
3165 owner_v[0] = strdup(AceDn);
3166 n = 0;
3167 ADD_ATTR("owner", owner_v, LDAP_MOD_REPLACE);
3168
3169 mods[n] = NULL;
3170
3171 rc = ldap_modify_s(ldap_handle, TargetDn, mods);
3172
3173 for (i = 0; i < n; i++)
3174 free(mods[i]);
3175
3176 if (rc != LDAP_SUCCESS)
3177 com_err(whoami, 0, "Unable to set owner for group %s : %s",
3178 TargetGroupName, ldap_err2string(rc));
3179 }
3180
3181 return(rc);
3182 }
3183
3184 if (AceSidCount == 0)
3185 {
3186 com_err(whoami, 0, "Group %s: Administrator: %s, Type: %s - does not "
c9ef9269 3187 "have a directory SID.", TargetGroupName, AceName, AceType);
61a2844b 3188 com_err(whoami, 0, " Non-admin security group template will be used.");
3189 }
3190 else
3191 {
3192 sprintf(search_path, "%s,%s", security_template_ou, dn_path);
3193 sprintf(filter_exp, "(sAMAccountName=%s)", "UserTemplate.u");
3194 attr_array[0] = "objectSid";
3195 attr_array[1] = NULL;
3196
3197 group_count = 0;
3198 group_base = NULL;
3199
3200 if ((rc = linklist_build(ldap_handle, search_path, filter_exp,
3201 attr_array, &group_base, &group_count,
3202 LDAP_SCOPE_SUBTREE) != 0))
3203 return(1);
3204
3205 if ((rc != 0) || (group_count != 1))
3206 {
3207 com_err(whoami, 0, "Unable to process user security template: %s",
3208 "UserTemplate");
3209 AceSidCount = 0;
3210 }
3211 else
3212 {
3213 UserTemplateSidCount = group_base->length;
3214 memcpy(UserTemplateSid, group_base->value, UserTemplateSidCount);
3215 }
3216 linklist_free(group_base);
3217 group_base = NULL;
3218 group_count = 0;
3219 }
3220
3221 if (HiddenGroup)
3222 {
3223 if (AceSidCount == 0)
3224 {
3225 strcpy(GroupSecurityTemplate, HIDDEN_GROUP);
3226 sprintf(filter_exp, "(sAMAccountName=%s)", HIDDEN_GROUP);
3227 }
3228 else
3229 {
3230 strcpy(GroupSecurityTemplate, HIDDEN_GROUP_WITH_ADMIN);
3231 sprintf(filter_exp, "(sAMAccountName=%s)", HIDDEN_GROUP_WITH_ADMIN);
3232 }
3233 }
3234 else
3235 {
3236 if (AceSidCount == 0)
3237 {
3238 strcpy(GroupSecurityTemplate, NOT_HIDDEN_GROUP);
3239 sprintf(filter_exp, "(sAMAccountName=%s)", NOT_HIDDEN_GROUP);
3240 }
3241 else
3242 {
3243 strcpy(GroupSecurityTemplate, NOT_HIDDEN_GROUP_WITH_ADMIN);
3244 sprintf(filter_exp, "(sAMAccountName=%s)",
3245 NOT_HIDDEN_GROUP_WITH_ADMIN);
3246 }
3247 }
3248
3249 sprintf(search_path, "%s,%s", security_template_ou, dn_path);
3250 attr_array[0] = "sAMAccountName";
3251 attr_array[1] = NULL;
3252 group_count = 0;
3253 group_base = NULL;
3254
3255 if ((rc = linklist_build(ldap_handle, search_path, filter_exp, attr_array,
3256 &group_base, &group_count,
3257 LDAP_SCOPE_SUBTREE) != 0))
3258 return(1);
3259
3260 if (group_count != 1)
3261 {
3262 linklist_free(group_base);
3263 com_err(whoami, 0, "Unable to process group security template: %s - "
3264 "security not set", GroupSecurityTemplate);
3265 return(1);
3266 }
3267
3268 strcpy(TemplateDn, group_base->dn);
3269 strcpy(TemplateSamName, group_base->value);
3270 linklist_free(group_base);
3271 group_base = NULL;
3272 group_count = 0;
3273
3274 sprintf(filter_exp, "(sAMAccountName=%s)", TemplateSamName);
3275 rc = ldap_search_ext_s(ldap_handle,
3276 TemplateDn,
3277 LDAP_SCOPE_SUBTREE,
3278 filter_exp,
3279 NULL,
3280 0,
3281 apsServerControls,
3282 NULL,
3283 NULL,
3284 0,
3285 &psMsg);
3286
3287 if ((psMsg = ldap_first_entry(ldap_handle, psMsg)) == NULL)
3288 {
3289 com_err(whoami, 0, "Unable to find group security template: %s - "
3290 "security not set", GroupSecurityTemplate);
3291 return(1);
3292 }
3293
3294 ppsValues = ldap_get_values_len(ldap_handle, psMsg, "ntSecurityDescriptor");
3295
3296 if (ppsValues == NULL)
3297 {
3298 com_err(whoami, 0, "Unable to find group security descriptor for group "
3299 "%s - security not set", GroupSecurityTemplate);
3300 return(1);
3301 }
3302
3303 if (AceSidCount != 0)
3304 {
3305 for (nVal = 0; ppsValues[nVal] != NULL; nVal++)
3306 {
3307 for (i = 0;
3308 i < (int)(ppsValues[nVal]->bv_len - UserTemplateSidCount); i++)
3309 {
3310 if (!memcmp(&ppsValues[nVal]->bv_val[i], UserTemplateSid,
3311 UserTemplateSidCount))
3312 {
3313 memcpy(&ppsValues[nVal]->bv_val[i], AceSid, AceSidCount);
3314 break;
3315 }
3316 }
3317 }
3318 }
3319
3320 n = 0;
3321 ADD_ATTR("ntSecurityDescriptor", (char **)ppsValues,
3322 LDAP_MOD_REPLACE | LDAP_MOD_BVALUES);
3323
3324 if (Exchange)
3325 {
3326 if(HiddenGroup)
3327 {
3328 hide_address_lists_v[0] = "TRUE";
3329 address_book_v[0] = NULL;
3330 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
3331 LDAP_MOD_REPLACE);
3332 ADD_ATTR("showInAddressBook", address_book_v, LDAP_MOD_REPLACE);
3333 } else {
3334 hide_address_lists_v[0] = NULL;
3335 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
3336 LDAP_MOD_REPLACE);
3337 }
3338 }
3339
3340 mods[n] = NULL;
3341
3342 rc = ldap_modify_s(ldap_handle, TargetDn, mods);
3343
3344 for (i = 0; i < n; i++)
3345 free(mods[i]);
3346
3347 ldap_value_free_len(ppsValues);
3348 ldap_msgfree(psMsg);
3349
3350 if (rc != LDAP_SUCCESS)
3351 {
3352 com_err(whoami, 0, "Unable to set security settings for group %s : %s",
3353 TargetGroupName, ldap_err2string(rc));
3354
3355 if (AceSidCount != 0)
3356 {
3357 com_err(whoami, 0,
3358 "Trying to set security for group %s without admin.",
3359 TargetGroupName);
3360
3361 if (rc = ProcessGroupSecurity(ldap_handle, dn_path, TargetGroupName,
3362 HiddenGroup, "", ""))
3363 {
3364 com_err(whoami, 0, "Unable to set security for group %s.",
3365 TargetGroupName);
3366 return(rc);
3367 }
3368 }
3369 return(rc);
3370 }
3371
3372 return(rc);
3373}
3374
3375int group_delete(LDAP *ldap_handle, char *dn_path, char *group_name,
3376 char *group_membership, char *MoiraId)
3377{
3378 LK_ENTRY *group_base;
3379 char temp[512];
3380 char filter[128];
3381 int group_count;
3382 int rc;
3383
3384 if (!check_string(group_name))
3385 {
3386 com_err(whoami, 0,
3387 "Unable to process invalid LDAP list name %s", group_name);
3388 return(AD_INVALID_NAME);
3389 }
3390
3391 memset(filter, '\0', sizeof(filter));
3392 group_count = 0;
3393 group_base = NULL;
3394 sprintf(temp, "%s,%s", group_ou_root, dn_path);
3395
3396 if (rc = ad_get_group(ldap_handle, temp, group_name,
3397 group_membership, MoiraId,
3398 "samAccountName", &group_base,
3399 &group_count, filter))
3400 return(rc);
3401
3402 if (group_count == 1)
3403 {
3404 if ((rc = ldap_delete_s(ldap_handle, group_base->dn)) != LDAP_SUCCESS)
3405 {
3406 linklist_free(group_base);
c9ef9269 3407 com_err(whoami, 0, "Unable to delete list %s from directory : %s",
61a2844b 3408 group_name, ldap_err2string(rc));
3409 return(rc);
3410 }
3411 linklist_free(group_base);
3412 }
3413 else
3414 {
3415 linklist_free(group_base);
c9ef9269 3416 com_err(whoami, 0, "Unable to find list %s in directory.", group_name);
61a2844b 3417 return(AD_NO_GROUPS_FOUND);
3418 }
3419
3420 return(0);
3421}
3422
3423int BEREncodeSecurityBits(ULONG uBits, char *pBuffer)
3424{
3425 *pBuffer++ = 0x30;
3426 *pBuffer++ = 0x03;
3427 *pBuffer++ = 0x02;
3428 *pBuffer++ = 0x00;
3429 return(N_SD_BER_BYTES);
3430}
3431
3432int process_lists(int ac, char **av, void *ptr)
3433{
3434 int rc;
3435 int security_flag;
3436 char group_ou[256];
3437 char group_membership[2];
3438 char **call_args;
3439
3440 call_args = ptr;
3441
3442 security_flag = 0;
3443 memset(group_ou, '\0', sizeof(group_ou));
3444 memset(group_membership, '\0', sizeof(group_membership));
3445 get_group_membership(group_membership, group_ou, &security_flag, av);
3446 rc = populate_group((LDAP *)call_args[0], (char *)call_args[1],
3447 av[L_NAME], group_ou, group_membership,
3448 security_flag, "");
3449
3450 return(0);
3451}
3452
3453int member_list_build(int ac, char **av, void *ptr)
3454{
3455 LK_ENTRY *linklist;
3456 char temp[1024];
3457 char **call_args;
3458 char *s;
3459 call_args = ptr;
0d2076dc 3460
61a2844b 3461 strcpy(temp, av[ACE_NAME]);
c9ef9269 3462 StringTrim(temp);
3463
61a2844b 3464 if (!check_string(temp))
3465 return(0);
3466
3467 if (!strcmp(av[ACE_TYPE], "USER"))
3468 {
3469 if (!((int)call_args[3] & MOIRA_USERS))
3470 return(0);
3471 }
3472 else if (!strcmp(av[ACE_TYPE], "STRING"))
3473 {
3474 if (Exchange)
3475 {
3476 if((s = strchr(temp, '@')) == (char *) NULL)
3477 {
3478 strcat(temp, "@mit.edu");
3479 }
3480
3481 if(!strncasecmp(&temp[strlen(temp) - 6], ".LOCAL", 6))
3482 {
3483 s = strrchr(temp, '.');
3484 *s = '\0';
3485 strcat(s, ".mit.edu");
3486 }
3487 }
0d2076dc 3488
61a2844b 3489 if (!((int)call_args[3] & MOIRA_STRINGS))
3490 return(0);
0d2076dc 3491
61a2844b 3492 if (contact_create((LDAP *)call_args[0], call_args[1], temp, contact_ou))
3493 return(0);
61a2844b 3494 }
3495 else if (!strcmp(av[ACE_TYPE], "LIST"))
3496 {
3497 if (!((int)call_args[3] & MOIRA_LISTS))
3498 return(0);
3499 }
3500 else if (!strcmp(av[ACE_TYPE], "KERBEROS"))
3501 {
3502 if (!((int)call_args[3] & MOIRA_KERBEROS))
3503 return(0);
3504
3505 if (contact_create((LDAP *)call_args[0], call_args[1], temp,
3506 kerberos_ou))
3507 return(0);
3508
3509 }
e8332ac3 3510 else if (!strcmp(av[ACE_TYPE], "MACHINE"))
3511 {
3512 if (!((int)call_args[3] & MOIRA_MACHINE))
3513 return(0);
3514 }
61a2844b 3515 else
3516 return(0);
3517
3518 linklist = member_base;
3519
3520 while (linklist)
3521 {
0d2076dc 3522 if (!strcasecmp(temp, linklist->member) &&
3523 !strcasecmp(av[ACE_TYPE], linklist->type))
61a2844b 3524 return(0);
3525
3526 linklist = linklist->next;
3527 }
3528
3529 linklist = calloc(1, sizeof(LK_ENTRY));
3530 linklist->op = 1;
3531 linklist->dn = NULL;
3532 linklist->list = calloc(1, strlen(call_args[2]) + 1);
3533 strcpy(linklist->list, call_args[2]);
3534 linklist->type = calloc(1, strlen(av[ACE_TYPE]) + 1);
3535 strcpy(linklist->type, av[ACE_TYPE]);
3536 linklist->member = calloc(1, strlen(temp) + 1);
3537 strcpy(linklist->member, temp);
3538 linklist->next = member_base;
3539 member_base = linklist;
3540
3541 return(0);
3542}
3543
3544int member_remove(LDAP *ldap_handle, char *dn_path, char *group_name,
3545 char *group_ou, char *group_membership, char *user_name,
3546 char *UserOu, char *MoiraId)
3547{
3548 char distinguished_name[1024];
3549 char *modvalues[2];
3550 char temp[256];
3551 char filter[128];
3552 char *attr_array[3];
3553 int group_count;
3554 int i;
3555 int n;
3556 LDAPMod *mods[20];
3557 LK_ENTRY *group_base;
3558 ULONG rc;
3559 char *s;
3560
3561 if (!check_string(group_name))
3562 return(AD_INVALID_NAME);
3563
3564 memset(filter, '\0', sizeof(filter));
3565 group_base = NULL;
3566 group_count = 0;
3567
3568 if (rc = ad_get_group(ldap_handle, dn_path, group_name,
3569 group_membership, MoiraId,
3570 "samAccountName", &group_base,
3571 &group_count, filter))
3572 return(rc);
3573
3574 if (group_count != 1)
3575 {
c9ef9269 3576 com_err(whoami, 0, "Unable to find list %s in directory",
61a2844b 3577 group_name);
3578 linklist_free(group_base);
3579 group_base = NULL;
3580 group_count = 0;
3581 goto cleanup;
3582 }
3583
3584 strcpy(distinguished_name, group_base->dn);
3585 linklist_free(group_base);
3586 group_base = NULL;
3587 group_count = 0;
3588
3589 if(ActiveDirectory)
3590 {
3591 sprintf(temp, "CN=%s,%s,%s", user_name, UserOu, dn_path);
3592 }
3593 else
3594 {
3595 if(!strcmp(UserOu, user_ou))
3596 sprintf(temp, "uid=%s,%s,%s", user_name, UserOu, dn_path);
3597 else
3598 sprintf(temp, "CN=%s,%s,%s", user_name, UserOu, dn_path);
3599 }
3600
3601 modvalues[0] = temp;
3602 modvalues[1] = NULL;
3603
3604 n = 0;
3605 ADD_ATTR("member", modvalues, LDAP_MOD_DELETE);
3606 mods[n] = NULL;
3607 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
3608
3609 for (i = 0; i < n; i++)
3610 free(mods[i]);
3611
3612 if (rc == LDAP_UNWILLING_TO_PERFORM)
3613 rc = LDAP_SUCCESS;
3614
3615 if (rc != LDAP_SUCCESS)
3616 {
3617 com_err(whoami, 0, "Unable to modify list %s members : %s",
3618 group_name, ldap_err2string(rc));
3619 goto cleanup;
3620 }
3621
3622 if ((!strcmp(UserOu, contact_ou)) || (!strcmp(UserOu, kerberos_ou)))
3623 {
3624 if (Exchange)
3625 {
3626 if(!strcmp(UserOu, contact_ou) &&
3627 ((s = strstr(user_name, "@mit.edu")) != (char *) NULL))
3628 {
3629 memset(temp, '\0', sizeof(temp));
3630 strcpy(temp, user_name);
3631 s = strchr(temp, '@');
3632 *s = '\0';
3633
3634 sprintf(filter, "(&(objectClass=user)(mailNickName=%s))", temp);
3635
3636 if ((rc = linklist_build(ldap_handle, dn_path, filter, NULL,
3637 &group_base, &group_count,
3638 LDAP_SCOPE_SUBTREE) != 0))
3639 return(rc);
3640
3641 if(group_count)
3642 goto cleanup;
3643
3644 linklist_free(group_base);
3645 group_base = NULL;
3646 group_count = 0;
3647 }
3648
3649 sprintf(filter, "(distinguishedName=%s)", temp);
3650 attr_array[0] = "memberOf";
3651 attr_array[1] = NULL;
3652
3653 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
3654 &group_base, &group_count,
3655 LDAP_SCOPE_SUBTREE) != 0))
3656 return(rc);
3657
3658
3659 if(!group_count)
3660 {
3661 com_err(whoami, 0, "Removing unreferenced object %s", temp);
3662
3663 if ((rc = ldap_delete_s(ldap_handle, temp)) != 0)
3664 return(rc);
3665 }
3666 }
3667 }
3668
3669 cleanup:
3670 return(rc);
3671}
3672
3673int member_add(LDAP *ldap_handle, char *dn_path, char *group_name,
3674 char *group_ou, char *group_membership, char *user_name,
3675 char *UserOu, char *MoiraId)
3676{
3677 char distinguished_name[1024];
3678 char *modvalues[2];
3679 char temp[256];
3680 char filter[128];
3681 int group_count;
3682 int n;
3683 int i;
3684 LDAPMod *mods[20];
3685 LK_ENTRY *group_base;
3686 ULONG rc;
3687
3688 if (!check_string(group_name))
3689 return(AD_INVALID_NAME);
3690
3691 rc = 0;
3692 memset(filter, '\0', sizeof(filter));
3693 group_base = NULL;
3694 group_count = 0;
3695
3696 if (rc = ad_get_group(ldap_handle, dn_path, group_name,
3697 group_membership, MoiraId,
3698 "samAccountName", &group_base,
3699 &group_count, filter))
3700 return(rc);
3701
3702 if (group_count != 1)
3703 {
3704 linklist_free(group_base);
3705 group_base = NULL;
3706 group_count = 0;
c9ef9269 3707 com_err(whoami, 0, "Unable to find list %s %d in directory",
61a2844b 3708 group_name, group_count);
3709 return(AD_MULTIPLE_GROUPS_FOUND);
3710 }
3711
3712 strcpy(distinguished_name, group_base->dn);
3713 linklist_free(group_base);
3714 group_base = NULL;
3715 group_count = 0;
3716
3717 if(ActiveDirectory)
3718 {
3719 sprintf(temp, "CN=%s,%s,%s", user_name, UserOu, dn_path);
3720 }
3721 else
3722 {
3723 if(!strcmp(UserOu, user_ou))
3724 sprintf(temp, "uid=%s,%s,%s", user_name, UserOu, dn_path);
3725 else
3726 sprintf(temp, "cn=%s,%s,%s", user_name, UserOu, dn_path);
3727 }
3728
3729 modvalues[0] = temp;
3730 modvalues[1] = NULL;
3731
3732 n = 0;
3733 ADD_ATTR("member", modvalues, LDAP_MOD_ADD);
3734 mods[n] = NULL;
3735 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
3736
3737 if (rc == LDAP_ALREADY_EXISTS || rc == LDAP_TYPE_OR_VALUE_EXISTS)
3738 rc = LDAP_SUCCESS;
3739
3740 if ((!strcmp(UserOu, contact_ou)) || (!strcmp(UserOu, kerberos_ou)))
3741 {
3742 if (rc == LDAP_UNWILLING_TO_PERFORM)
3743 rc = LDAP_SUCCESS;
3744 }
3745
3746 for (i = 0; i < n; i++)
3747 free(mods[i]);
3748
3749 if (rc != LDAP_SUCCESS)
3750 {
3751 com_err(whoami, 0, "Unable to add %s to list %s as a member : %s",
3752 user_name, group_name, ldap_err2string(rc));
3753 }
3754
3755 return(rc);
3756}
3757
3758int contact_remove_email(LDAP *ld, char *bind_path,
3759 LK_ENTRY **linklist_base, int linklist_current)
3760{
3761 LK_ENTRY *gPtr;
3762 int rc;
3763 char *mail_v[] = {NULL, NULL};
3764 LDAPMod *mods[20];
3765 int n;
3766 int i;
3767
3768 mail_v[0] = NULL;
3769
3770 n = 0;
3771 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
3772 ADD_ATTR("mailNickName", mail_v, LDAP_MOD_REPLACE);
3773 ADD_ATTR("proxyAddresses", mail_v, LDAP_MOD_REPLACE);
3774 ADD_ATTR("targetAddress", mail_v, LDAP_MOD_REPLACE);
3775 mods[n] = NULL;
3776
3777 gPtr = (*linklist_base);
3778
3779 while(gPtr) {
3780 rc = ldap_modify_s(ld, gPtr->dn, mods);
3781
3782 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
3783 {
c9ef9269 3784 com_err(whoami, 0, "Unable to modify contact %s in directory : %s",
61a2844b 3785 gPtr->dn, ldap_err2string(rc));
3786 return(rc);
3787 }
3788
3789 gPtr = gPtr->next;
3790 }
3791
3792 for (i = 0; i < n; i++)
3793 free(mods[i]);
3794
3795 return(rc);
3796}
3797
3798int contact_create(LDAP *ld, char *bind_path, char *user, char *group_ou)
3799{
3800 LDAPMod *mods[20];
3801 LK_ENTRY *group_base;
3802 int group_count;
3803 char new_dn[256];
3804 char cn_user_name[256];
3805 char contact_name[256];
3806 char mail_nickname[256];
3807 char proxy_address_internal[256];
3808 char proxy_address_external[256];
3809 char target_address[256];
3810 char internal_contact_name[256];
3811 char filter[128];
3812 char mail[256];
3813 char principal[256];
3814 char mit_address_book[256];
3815 char default_address_book[256];
3816 char contact_address_book[256];
3817 char uid[256];
3818 char *email_v[] = {NULL, NULL};
3819 char *cn_v[] = {NULL, NULL};
3820 char *contact_v[] = {NULL, NULL};
3821 char *uid_v[] = {NULL, NULL};
3822 char *mail_nickname_v[] = {NULL, NULL};
3823 char *proxy_address_internal_v[] = {NULL, NULL};
3824 char *proxy_address_external_v[] = {NULL, NULL};
3825 char *target_address_v[] = {NULL, NULL};
3826 char *mit_address_book_v[] = {NULL, NULL};
3827 char *default_address_book_v[] = {NULL, NULL};
3828 char *contact_address_book_v[] = {NULL, NULL};
3829 char *hide_address_lists_v[] = {NULL, NULL};
3830 char *attr_array[3];
3831 char *objectClass_v[] = {"top", "person",
3832 "organizationalPerson",
3833 "contact", NULL};
3834 char *objectClass_ldap_v[] = {"top", "person", "microsoftComTop",
3835 "inetOrgPerson", "organizationalPerson",
3836 "contact", "mailRecipient", "eduPerson",
3837 NULL};
3838 char *name_v[] = {NULL, NULL};
3839 char *desc_v[] = {NULL, NULL};
3840 char *s;
3841 int n;
3842 int rc;
3843 int i;
3844 char temp[256];
3845 char *c;
3846 char *mail_routing_v[] = {NULL, NULL};
3847 char *principal_v[] = {NULL, NULL};
3848
3849 if (!check_string(user))
3850 {
3851 com_err(whoami, 0, "Unable to process invalid LDAP name %s", user);
3852 return(AD_INVALID_NAME);
3853 }
3854
3855 strcpy(mail, user);
3856 strcpy(contact_name, mail);
3857 strcpy(internal_contact_name, mail);
3858
3859 if((s = strchr(internal_contact_name, '@')) != NULL) {
3860 *s = '?';
3861 }
3862
3863 sprintf(cn_user_name,"CN=%s,%s,%s", escape_string(contact_name), group_ou,
3864 bind_path);
3865
3866 sprintf(target_address, "SMTP:%s", contact_name);
3867 sprintf(proxy_address_external, "SMTP:%s", contact_name);
3868 sprintf(mail_nickname, "%s", internal_contact_name);
3869
3870 cn_v[0] = cn_user_name;
3871 contact_v[0] = contact_name;
3872 uid_v[0] = uid;
3873 name_v[0] = user;
3874 desc_v[0] = "Auto account created by Moira";
3875 email_v[0] = mail;
3876 proxy_address_internal_v[0] = proxy_address_internal;
3877 proxy_address_external_v[0] = proxy_address_external;
3878 mail_nickname_v[0] = mail_nickname;
3879 target_address_v[0] = target_address;
3880 mit_address_book_v[0] = mit_address_book;
3881 default_address_book_v[0] = default_address_book;
3882 contact_address_book_v[0] = contact_address_book;
3883 strcpy(new_dn, cn_user_name);
3884 n = 0;
3885
3886 ADD_ATTR("cn", contact_v, LDAP_MOD_ADD);
3887
3888 if(!ActiveDirectory)
3889 {
3890 if(!strcmp(group_ou, contact_ou))
3891 sprintf(uid, "%s%s", contact_name, "_strings");
3892
3893 if(!strcmp(group_ou, kerberos_ou))
3894 sprintf(uid, "%s%s", contact_name, "_kerberos");
3895
3896 uid_v[0] = uid;
3897
3898 ADD_ATTR("sn", contact_v, LDAP_MOD_ADD);
3899 ADD_ATTR("uid", uid_v, LDAP_MOD_ADD);
3900 }
3901
3902 if(ActiveDirectory)
3903 {
3904 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
3905 }
3906 else
3907 {
3908 ADD_ATTR("objectClass", objectClass_ldap_v, LDAP_MOD_ADD);
3909 }
3910
3911 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
3912 ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
3913 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
3914
3915 if (Exchange)
3916 {
3917 if (!strcmp(group_ou, contact_ou) && email_isvalid(mail))
3918 {
3919 group_count = 0;
3920 group_base = NULL;
3921
3922 sprintf(filter, "(&(objectClass=user)(cn=%s))", mail);
3923 attr_array[0] = "cn";
3924 attr_array[1] = NULL;
3925
3926 if ((rc = linklist_build(ld, bind_path, filter, attr_array,
3927 &group_base, &group_count,
3928 LDAP_SCOPE_SUBTREE)) != 0)
3929 {
3930 com_err(whoami, 0, "Unable to process contact %s : %s",
3931 user, ldap_err2string(rc));
3932 return(rc);
3933 }
3934
3935 if (group_count)
3936 {
3937 com_err(whoami, 0, "Object already exists with name %s",
3938 user);
3939 return(1);
3940 }
3941
3942 linklist_free(group_base);
3943 group_base = NULL;
3944 group_count = 0;
3945
3946 sprintf(filter, "(&(objectClass=group)(cn=%s))", mail);
3947 attr_array[0] = "cn";
3948 attr_array[1] = NULL;
3949
3950 if ((rc = linklist_build(ld, bind_path, filter, attr_array,
3951 &group_base, &group_count,
3952 LDAP_SCOPE_SUBTREE)) != 0)
3953 {
3954 com_err(whoami, 0, "Unable to process contact %s : %s",
3955 user, ldap_err2string(rc));
3956 return(rc);
3957 }
3958
3959 if (group_count)
3960 {
3961 com_err(whoami, 0, "Object already exists with name %s",
3962 user);
3963 return(1);
3964 }
3965
3966 linklist_free(group_base);
3967 group_count = 0;
3968 group_base = NULL;
3969
3970 sprintf(filter, "(&(objectClass=user)(mail=%s))", mail);
3971 attr_array[0] = "cn";
3972 attr_array[1] = NULL;
3973
3974 if ((rc = linklist_build(ld, bind_path, filter, attr_array,
3975 &group_base, &group_count,
3976 LDAP_SCOPE_SUBTREE)) != 0)
3977 {
3978 com_err(whoami, 0, "Unable to process contact %s : %s",
3979 user, ldap_err2string(rc));
3980 return(rc);
3981 }
3982
3983 if (group_count)
3984 {
3985 com_err(whoami, 0, "Object already exists with name %s",
3986 user);
3987 return(1);
3988 }
3989
3990 linklist_free(group_base);
3991 group_base = NULL;
3992 group_count = 0;
3993
3994 sprintf(filter, "(&(objectClass=group)(mail=%s))", mail);
3995 attr_array[0] = "cn";
3996 attr_array[1] = NULL;
3997
3998 if ((rc = linklist_build(ld, bind_path, filter, attr_array,
3999 &group_base, &group_count,
4000 LDAP_SCOPE_SUBTREE)) != 0)
4001 {
4002 com_err(whoami, 0, "Unable to process contact %s : %s",
4003 user, ldap_err2string(rc));
4004 return(rc);
4005 }
4006
4007 if (group_count)
4008 {
4009 com_err(whoami, 0, "Object already exists with name %s",
4010 user);
4011 return(1);
4012 }
4013
4014 linklist_free(group_base);
4015 group_base = NULL;
4016 group_count = 0;
4017
4018 ADD_ATTR("mail", email_v, LDAP_MOD_ADD);
4019 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_ADD);
4020 ADD_ATTR("proxyAddresses", proxy_address_external_v, LDAP_MOD_ADD);
4021 ADD_ATTR("targetAddress", target_address_v, LDAP_MOD_ADD);
4022
4023 hide_address_lists_v[0] = "TRUE";
4024 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
4025 LDAP_MOD_ADD);
4026 }
4027 }
4028
4029 if(!ActiveDirectory)
4030 {
4031 if((c = strchr(mail, '@')) == NULL)
4032 sprintf(temp, "%s@mit.edu", mail);
4033 else
4034 sprintf(temp, "%s", mail);
4035
4036 mail_routing_v[0] = temp;
4037 email_v[0] = temp;
4038 principal_v[0] = principal;
4039
4040 if(!strcmp(group_ou, contact_ou))
4041 {
4042 ADD_ATTR("mailRoutingAddress", mail_routing_v, LDAP_MOD_ADD);
61a2844b 4043 ADD_ATTR("eduPersonPrincipalName", mail_routing_v, LDAP_MOD_ADD);
4044 }
4045 }
4046
4047 mods[n] = NULL;
4048
4049 rc = ldap_add_ext_s(ld, new_dn, mods, NULL, NULL);
4050
4051 for (i = 0; i < n; i++)
4052 free(mods[i]);
4053
4054 if (Exchange)
4055 {
4056 if ((rc != LDAP_SUCCESS) && (rc == LDAP_ALREADY_EXISTS) &&
4057 !strcmp(group_ou, contact_ou) && email_isvalid(mail))
4058 {
4059 n = 0;
4060
4061 ADD_ATTR("mail", email_v, LDAP_MOD_REPLACE);
4062 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
4063 ADD_ATTR("proxyAddresses", proxy_address_external_v,
4064 LDAP_MOD_REPLACE);
4065 ADD_ATTR("targetAddress", target_address_v, LDAP_MOD_REPLACE);
4066
4067 hide_address_lists_v[0] = "TRUE";
4068 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
4069 LDAP_MOD_REPLACE);
4070
4071 mods[n] = NULL;
4072 rc = ldap_modify_s(ld, new_dn, mods);
4073
4074 if (rc)
4075 {
4076 com_err(whoami, 0, "Unable to update contact %s", mail);
4077 }
4078
4079 for (i = 0; i < n; i++)
4080 free(mods[i]);
4081 }
4082 }
4083
61a2844b 4084 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
4085 {
4086 com_err(whoami, 0, "Unable to create contact %s : %s",
4087 user, ldap_err2string(rc));
4088 return(rc);
4089 }
4090
4091 return(0);
4092}
4093
4094int user_update(LDAP *ldap_handle, char *dn_path, char *user_name,
4095 char *Uid, char *MitId, char *MoiraId, int State,
4096 char *WinHomeDir, char *WinProfileDir, char *first,
4097 char *middle, char *last, char *shell, char *class)
4098{
4099 LDAPMod *mods[20];
4100 LK_ENTRY *group_base;
4101 int group_count;
4102 char distinguished_name[512];
4103 char displayName[256];
4104 char *mitMoiraId_v[] = {NULL, NULL};
4105 char *mitMoiraClass_v[] = {NULL, NULL};
4106 char *mitMoiraStatus_v[] = {NULL, NULL};
4107 char *uid_v[] = {NULL, NULL};
4108 char *mitid_v[] = {NULL, NULL};
4109 char *homedir_v[] = {NULL, NULL};
4110 char *winProfile_v[] = {NULL, NULL};
4111 char *drives_v[] = {NULL, NULL};
4112 char *userAccountControl_v[] = {NULL, NULL};
4113 char *alt_recipient_v[] = {NULL, NULL};
4114 char *hide_address_lists_v[] = {NULL, NULL};
4115 char *mail_v[] = {NULL, NULL};
4116 char *gid_v[] = {NULL, NULL};
4117 char *loginshell_v[] = {NULL, NULL};
4118 char *principal_v[] = {NULL, NULL};
4119 char userAccountControlStr[80];
4120 int n;
4121 int rc;
4122 int i;
4123 int OldUseSFU30;
4124 u_int userAccountControl = UF_NORMAL_ACCOUNT | UF_DONT_EXPIRE_PASSWD |
4125 UF_PASSWD_CANT_CHANGE;
4126 char filter[128];
4127 char *attr_array[3];
4128 char temp[1024];
4129 char mail[256];
4130 char contact_mail[256];
4131 char filter_exp[1024];
4132 char search_path[512];
4133 char TemplateDn[512];
4134 char TemplateSamName[128];
4135 char alt_recipient[256];
4136 char principal[256];
4137 char status[256];
4138 char acBERBuf[N_SD_BER_BYTES];
4139 LDAPControl sControl = {"1.2.840.113556.1.4.801",
4140 { N_SD_BER_BYTES, acBERBuf },
4141 TRUE};
4142 LDAPControl *apsServerControls[] = {&sControl, NULL};
4143 LDAPMessage *psMsg;
4144 LDAP_BERVAL **ppsValues;
4145 ULONG dwInfo;
4146 char *argv[3];
4147 char *homeMDB;
4148 char *homeServerName;
4149 char *save_argv[7];
4150 char search_string[256];
4151 char *p, *q;
4152 char *mail_routing_v[] = {NULL, NULL};
4153 char *c;
4154
4155 dwInfo = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
4156 DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION;
4157 BEREncodeSecurityBits(dwInfo, acBERBuf);
4158
4159 if (!check_string(user_name))
4160 {
4161 com_err(whoami, 0, "Unable to process invalid LDAP user name %s",
4162 user_name);
4163 return(AD_INVALID_NAME);
4164 }
4165
4166 memset(contact_mail, '\0', sizeof(contact_mail));
4167 sprintf(contact_mail, "%s@mit.edu", user_name);
4168 memset(mail, '\0', sizeof(mail));
4169 sprintf(mail, "%s@%s", user_name, lowercase(ldap_domain));
4170 memset(alt_recipient, '\0', sizeof(alt_recipient));
4171 sprintf(alt_recipient, "cn=%s@mit.edu,%s,%s", user_name, contact_ou,
4172 dn_path);
4173 sprintf(search_string, "@%s", uppercase(ldap_domain));
4174
4175 if (Exchange)
4176 {
4177 if(contact_create(ldap_handle, dn_path, contact_mail, contact_ou))
4178 {
4179 com_err(whoami, 0, "Unable to create user contact %s", contact_mail);
4180 }
4181 }
4182
4183 group_count = 0;
4184 group_base = NULL;
4185
4186 memset(displayName, '\0', sizeof(displayName));
4187
4188 if (strlen(MoiraId) != 0)
4189 {
4190 if(ActiveDirectory)
4191 {
4192 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
4193 }
4194 else
4195 {
4196 sprintf(filter,
4197 "(&(objectClass=mitPerson)(mitMoiraId=%s))", MoiraId);
4198 }
4199
4200 attr_array[0] = "cn";
4201 attr_array[1] = NULL;
4202 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
4203 &group_base, &group_count,
4204 LDAP_SCOPE_SUBTREE)) != 0)
4205 {
4206 com_err(whoami, 0, "Unable to process user %s : %s",
4207 user_name, ldap_err2string(rc));
4208 return(rc);
4209 }
4210 }
4211
4212 if (group_count != 1)
4213 {
4214 linklist_free(group_base);
4215 group_base = NULL;
4216 group_count = 0;
4217 sprintf(filter, "(sAMAccountName=%s)", user_name);
4218 attr_array[0] = "cn";
4219 attr_array[1] = NULL;
4220 sprintf(temp, "%s,%s", user_ou, dn_path);
4221 if ((rc = linklist_build(ldap_handle, temp, filter, attr_array,
4222 &group_base, &group_count,
4223 LDAP_SCOPE_SUBTREE)) != 0)
4224 {
4225 com_err(whoami, 0, "Unable to process user %s : %s",
4226 user_name, ldap_err2string(rc));
4227 return(rc);
4228 }
4229 }
4230
4231 if (group_count != 1)
4232 {
c9ef9269 4233 com_err(whoami, 0, "Unable to find user %s in directory",
61a2844b 4234 user_name);
4235 linklist_free(group_base);
4236 return(AD_NO_USER_FOUND);
4237 }
4238
4239 strcpy(distinguished_name, group_base->dn);
4240
4241 linklist_free(group_base);
4242 group_count = 0;
4243
4244 if(!ActiveDirectory)
4245 {
4246 if (rc = moira_connect())
4247 {
c9ef9269 4248 critical_alert("Ldap incremental",
61a2844b 4249 "Error contacting Moira server : %s",
4250 error_message(rc));
4251 return;
4252 }
4253
4254 argv[0] = user_name;
4255
4256 if (!(rc = mr_query("get_pobox", 1, argv, save_query_info, save_argv)))
4257 {
4258 n = 0;
4259 ADD_ATTR("mailRoutingAddress", mail_routing_v, LDAP_MOD_REPLACE);
4260 mods[n] = NULL;
4261 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
4262
4263 if (rc == LDAP_ALREADY_EXISTS || rc == LDAP_TYPE_OR_VALUE_EXISTS)
4264 rc = LDAP_SUCCESS;
4265
4266 if(rc)
4267 com_err(whoami, 0,
4268 "Unable to set the mailRoutingAddress for %s : %s",
4269 user_name, ldap_err2string(rc));
4270
4271 p = strdup(save_argv[3]);
4272
4273 if((c = strchr(p, ',')) != NULL)
4274 {
4275 q = strtok(p, ",");
4276 StringTrim(q);
4277
4278 if ((c = strchr(q, '@')) == NULL)
4279 sprintf(temp, "%s@mit.edu", q);
4280 else
4281 sprintf(temp, "%s", q);
4282
4283 if(email_isvalid(temp) && State != US_DELETED)
4284 {
4285 mail_routing_v[0] = temp;
4286
4287 n = 0;
4288 ADD_ATTR("mailRoutingAddress", mail_routing_v, LDAP_MOD_ADD);
4289 mods[n] = NULL;
4290 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
4291
4292 if (rc == LDAP_ALREADY_EXISTS ||
4293 rc == LDAP_TYPE_OR_VALUE_EXISTS)
4294 rc = LDAP_SUCCESS;
4295
4296 if(rc)
4297 com_err(whoami, 0,
4298 "Unable to set the mailRoutingAddress for %s : %s",
4299 user_name, ldap_err2string(rc));
4300 }
4301
4302 while((q = strtok(NULL, ",")) != NULL) {
4303 StringTrim(q);
4304
4305 if((c = strchr(q, '@')) == NULL)
4306 sprintf(temp, "%s@mit.edu", q);
4307 else
4308 sprintf(temp, "%s", q);
4309
4310 if(email_isvalid(temp) && State != US_DELETED)
4311 {
4312 mail_routing_v[0] = temp;
4313
4314 n = 0;
4315 ADD_ATTR("mailRoutingAddress", mail_routing_v,
4316 LDAP_MOD_ADD);
4317 mods[n] = NULL;
4318 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
4319
4320 if (rc == LDAP_ALREADY_EXISTS ||
4321 rc == LDAP_TYPE_OR_VALUE_EXISTS)
4322 rc = LDAP_SUCCESS;
4323
4324 if(rc)
4325 com_err(whoami, 0,
4326 "Unable to set the mailRoutingAddress for "
4327 "%s : %s",
4328 user_name, ldap_err2string(rc));
4329 }
4330 }
4331 } else {
4332 StringTrim(p);
4333
4334 if((c = strchr(p, '@')) == NULL)
4335 sprintf(temp, "%s@mit.edu", p);
4336 else
4337 sprintf(temp, "%s", p);
4338
4339 if(email_isvalid(temp) && State != US_DELETED)
4340 {
4341 mail_routing_v[0] = temp;
4342
4343 n = 0;
4344 ADD_ATTR("mailRoutingAddress", mail_routing_v, LDAP_MOD_ADD);
4345 mods[n] = NULL;
4346 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
4347
4348 if (rc == LDAP_ALREADY_EXISTS ||
4349 rc == LDAP_TYPE_OR_VALUE_EXISTS)
4350 rc = LDAP_SUCCESS;
4351
4352 if(rc)
4353 com_err(whoami, 0,
4354 "Unable to set the mailRoutingAddress for %s : %s",
4355 user_name, ldap_err2string(rc));
4356 }
4357 }
4358 }
4359 moira_disconnect();
4360 }
4361
4362 if ((strlen(MitId) != 0) && (MitId[0] == '9'))
4363 rc = attribute_update(ldap_handle, distinguished_name, MitId,
4364 "employeeID", user_name);
4365 else
4366 rc = attribute_update(ldap_handle, distinguished_name, "none",
4367 "employeeID", user_name);
4368
4369 if(strlen(first)) {
4370 strcat(displayName, first);
4371 }
4372
4373 if(strlen(middle)) {
4374 if(strlen(first))
4375 strcat(displayName, " ");
4376
4377 strcat(displayName, middle);
4378 }
4379
4380 if(strlen(last)) {
4381 if(strlen(middle) || strlen(first))
4382 strcat(displayName, " ");
4383
4384 strcat(displayName, last);
4385 }
4386
4387 if(strlen(displayName))
4388 rc = attribute_update(ldap_handle, distinguished_name, displayName,
4389 "displayName", user_name);
4390 else
4391 rc = attribute_update(ldap_handle, distinguished_name, user_name,
4392 "displayName", user_name);
4393
4394 if(!ActiveDirectory)
4395 {
4396 if(strlen(displayName))
4397 rc = attribute_update(ldap_handle, distinguished_name, displayName,
4398 "cn", user_name);
4399 else
4400 rc = attribute_update(ldap_handle, distinguished_name, user_name,
4401 "cn", user_name);
4402 }
4403
4404 if(!ActiveDirectory)
4405 {
4406 rc = attribute_update(ldap_handle, distinguished_name, displayName,
4407 "eduPersonNickname", user_name);
4408 }
4409
4410 if(strlen(first))
4411 rc = attribute_update(ldap_handle, distinguished_name, first,
4412 "givenName", user_name);
4413 else
4414 rc = attribute_update(ldap_handle, distinguished_name, "",
4415 "givenName", user_name);
4416
4417 if(strlen(middle) == 1)
4418 rc = attribute_update(ldap_handle, distinguished_name, middle,
4419 "initials", user_name);
4420 else
4421 rc = attribute_update(ldap_handle, distinguished_name, "",
4422 "initials", user_name);
4423
4424 if(strlen(last))
4425 rc = attribute_update(ldap_handle, distinguished_name, last,
4426 "sn", user_name);
4427 else
4428 rc = attribute_update(ldap_handle, distinguished_name, "",
4429 "sn", user_name);
4430
4431 if(ActiveDirectory)
4432 {
4433 rc = attribute_update(ldap_handle, distinguished_name, Uid, "uid",
4434 user_name);
4435 }
4436 else
4437 {
4438 rc = attribute_update(ldap_handle, distinguished_name, user_name, "uid",
4439 user_name);
4440 }
4441
4442 rc = attribute_update(ldap_handle, distinguished_name, MoiraId,
4443 "mitMoiraId", user_name);
4444
4445 n = 0;
4446 uid_v[0] = Uid;
4447
4448 if(ActiveDirectory)
4449 {
4450 if (!UseSFU30)
4451 {
4452 ADD_ATTR("uidNumber", uid_v, LDAP_MOD_REPLACE);
4453 }
4454 else
4455 {
4456 ADD_ATTR("msSFU30UidNumber", uid_v, LDAP_MOD_REPLACE);
4457 }
4458 }
4459 else
4460 {
4461 sprintf(principal, "%s@%s", user_name, PRIMARY_REALM);
4462 sprintf(status, "%d", State);
4463 principal_v[0] = principal;
4464 loginshell_v[0] = shell;
4465 mitMoiraClass_v[0] = class;
4466 mitMoiraStatus_v[0] = status;
4467 gid_v[0] = "101";
4468 ADD_ATTR("uidNumber", uid_v, LDAP_MOD_REPLACE);
4469 ADD_ATTR("gidNumber", gid_v, LDAP_MOD_REPLACE);
4470 ADD_ATTR("loginShell", loginshell_v, LDAP_MOD_REPLACE);
4471 ADD_ATTR("eduPersonPrincipalName", mail_v, LDAP_MOD_REPLACE);
4472 ADD_ATTR("mitMoiraClass", mitMoiraClass_v, LDAP_MOD_REPLACE);
4473 ADD_ATTR("mitMoiraStatus", mitMoiraStatus_v, LDAP_MOD_REPLACE);
4474 }
4475
4476 if ((State != US_NO_PASSWD) && (State != US_REGISTERED))
4477 {
4478 userAccountControl |= UF_ACCOUNTDISABLE;
4479
4480 if (Exchange)
4481 {
4482 hide_address_lists_v[0] = "TRUE";
4483 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
4484 LDAP_MOD_REPLACE);
4485 }
4486 }
4487 else
4488 {
4489 if (Exchange)
4490 {
4491 hide_address_lists_v[0] = NULL;
4492 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
4493 LDAP_MOD_REPLACE);
4494 }
4495 }
4496
4497 sprintf(userAccountControlStr, "%ld", userAccountControl);
4498 userAccountControl_v[0] = userAccountControlStr;
4499 ADD_ATTR("userAccountControl", userAccountControl_v, LDAP_MOD_REPLACE);
4500
4501 if (Exchange)
4502 {
4503 if (rc = moira_connect())
4504 {
c9ef9269 4505 critical_alert("Ldap incremental",
61a2844b 4506 "Error contacting Moira server : %s",
4507 error_message(rc));
4508 return;
4509 }
4510
4511 argv[0] = user_name;
4512
4513 if (!(rc = mr_query("get_pobox", 1, argv, save_query_info, save_argv)))
4514 {
4515 if(!strcmp(save_argv[1], "EXCHANGE") ||
4516 (strstr(save_argv[3], search_string) != NULL))
4517 {
4518 alt_recipient_v[0] = NULL;
4519 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_REPLACE);
4520
4521 argv[0] = exchange_acl;
4522 argv[1] = "USER";
4523 argv[2] = user_name;
4524
4525 rc = mr_query("add_member_to_list", 3, argv, NULL, NULL);
4526
4527 if ((rc) && (rc != MR_EXISTS))
4528 {
4529 com_err(whoami, 0, "Unable to add user %s to %s: %s",
4530 user_name, exchange_acl, error_message(rc));
4531 }
4532 }
4533 else
4534 {
4535 alt_recipient_v[0] = alt_recipient;
4536 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_REPLACE);
4537
4538 argv[0] = exchange_acl;
4539 argv[1] = "USER";
4540 argv[2] = user_name;
4541
4542 rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL);
4543
4544 if ((rc) && (rc != MR_NO_MATCH))
4545 {
4546 com_err(whoami, 0,
4547 "Unable to remove user %s from %s: %s, %d",
4548 user_name, exchange_acl, error_message(rc), rc);
4549 }
4550 }
4551 }
4552 else
4553 {
4554 alt_recipient_v[0] = alt_recipient;
4555 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_REPLACE);
4556
4557 argv[0] = exchange_acl;
4558 argv[1] = "USER";
4559 argv[2] = user_name;
4560
4561 rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL);
4562
4563 if ((rc) && (rc != MR_NO_MATCH))
4564 {
4565 com_err(whoami, 0,
4566 "Unable to remove user %s from %s: %s, %d",
4567 user_name, exchange_acl, error_message(rc), rc);
4568 }
4569 }
4570
4571 moira_disconnect();
4572 }
4573 else
4574 {
4575 mail_v[0] = contact_mail;
4576 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
08ca7a3e 4577
4578 if(!ActiveDirectory)
4579 {
4580 ADD_ATTR("mitMoiraMail", mail_v, LDAP_MOD_REPLACE);
4581 }
61a2844b 4582 }
4583
4584 n = SetHomeDirectory(ldap_handle, user_name, distinguished_name, WinHomeDir,
4585 WinProfileDir, homedir_v, winProfile_v,
4586 drives_v, mods, LDAP_MOD_REPLACE, n);
4587
4588 if(ActiveDirectory)
4589 {
4590 sprintf(filter_exp, "(sAMAccountName=%s)", "UserTemplate.u");
4591 sprintf(search_path, "%s,%s", security_template_ou, dn_path);
4592 attr_array[0] = "sAMAccountName";
4593 attr_array[1] = NULL;
4594 group_count = 0;
4595 group_base = NULL;
4596
4597 if ((rc = linklist_build(ldap_handle, search_path, filter_exp,
4598 attr_array,
4599 &group_base, &group_count,
4600 LDAP_SCOPE_SUBTREE) != 0))
4601 return(1);
4602
4603 if (group_count != 1)
4604 {
4605 com_err(whoami, 0, "Unable to process user security template: %s - "
4606 "security not set", "UserTemplate.u");
4607 return(1);
4608 }
4609
4610 strcpy(TemplateDn, group_base->dn);
4611 strcpy(TemplateSamName, group_base->value);
4612 linklist_free(group_base);
4613 group_base = NULL;
4614 group_count = 0;
4615
4616 rc = ldap_search_ext_s(ldap_handle, search_path, LDAP_SCOPE_SUBTREE,
4617 filter_exp, NULL, 0, apsServerControls, NULL,
4618 NULL, 0, &psMsg);
4619
4620 if ((psMsg = ldap_first_entry(ldap_handle, psMsg)) == NULL)
4621 {
4622 com_err(whoami, 0, "Unable to find user security template: %s - "
4623 "security not set", "UserTemplate.u");
4624 return(1);
4625 }
4626
4627 ppsValues = ldap_get_values_len(ldap_handle, psMsg,
4628 "ntSecurityDescriptor");
4629
4630 if (ppsValues == NULL)
4631 {
4632 com_err(whoami, 0, "Unable to find user security template: %s - "
4633 "security not set", "UserTemplate.u");
4634 return(1);
4635 }
4636
4637 ADD_ATTR("ntSecurityDescriptor", (char **)ppsValues,
4638 LDAP_MOD_REPLACE | LDAP_MOD_BVALUES);
4639 }
4640
4641 mods[n] = NULL;
4642
4643 if ((rc = ldap_modify_s(ldap_handle, distinguished_name,
4644 mods)) != LDAP_SUCCESS)
4645 {
4646 OldUseSFU30 = UseSFU30;
4647 SwitchSFU(mods, &UseSFU30, n);
4648 if (OldUseSFU30 != UseSFU30)
4649 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
4650 if (rc)
4651 {
4652 com_err(whoami, 0, "Unable to modify user data for %s : %s",
4653 user_name, ldap_err2string(rc));
4654 }
4655 }
4656
4657 for (i = 0; i < n; i++)
4658 free(mods[i]);
4659
4660 return(rc);
4661}
4662
4663int user_rename(LDAP *ldap_handle, char *dn_path, char *before_user_name,
4664 char *user_name)
4665{
4666 LDAPMod *mods[20];
4667 char new_dn[256];
4668 char old_dn[256];
4669 char upn[256];
4670 char mail[256];
4671 char contact_mail[256];
4672 char proxy_address[256];
4673 char query_base_dn[256];
4674 char temp[256];
4675 char *userPrincipalName_v[] = {NULL, NULL};
4676 char *altSecurityIdentities_v[] = {NULL, NULL};
4677 char *name_v[] = {NULL, NULL};
4678 char *samAccountName_v[] = {NULL, NULL};
4679 char *mail_v[] = {NULL, NULL};
4680 char *mail_nickname_v[] = {NULL, NULL};
4681 char *proxy_address_v[] = {NULL, NULL};
4682 char *query_base_dn_v[] = {NULL, NULL};
4683 char *principal_v[] = {NULL, NULL};
4684 char principal[256];
4685 int n;
4686 int rc;
4687 int i;
4688
4689 if (!check_string(before_user_name))
4690 {
4691 com_err(whoami, 0,
4692 "Unable to process invalid LDAP user name %s", before_user_name);
4693 return(AD_INVALID_NAME);
4694 }
4695
4696 if (!check_string(user_name))
4697 {
4698 com_err(whoami, 0,
4699 "Unable to process invalid LDAP user name %s", user_name);
4700 return(AD_INVALID_NAME);
4701 }
4702
4703 strcpy(user_name, user_name);
4704
4705 if(ActiveDirectory)
4706 sprintf(old_dn, "cn=%s,%s,%s", before_user_name, user_ou, dn_path);
4707 else
4708 sprintf(old_dn, "uid=%s,%s,%s", before_user_name, user_ou, dn_path);
4709
4710 if(ActiveDirectory)
4711 sprintf(new_dn, "cn=%s", user_name);
4712 else
4713 sprintf(new_dn, "uid=%s", user_name);
4714
4715 sprintf(mail, "%s@%s", user_name, lowercase(ldap_domain));
4716 sprintf(contact_mail, "%s@mit.edu", user_name);
4717 sprintf(proxy_address, "SMTP:%s@%s", user_name, lowercase(ldap_domain));
4718 sprintf(principal, "%s@%s", user_name, PRIMARY_REALM);
4719
4720 if ((rc = ldap_rename_s(ldap_handle, old_dn, new_dn, NULL, TRUE,
4721 NULL, NULL)) != LDAP_SUCCESS)
4722 {
4723 com_err(whoami, 0, "Unable to rename user from %s to %s : %s",
4724 before_user_name, user_name, ldap_err2string(rc));
4725 return(rc);
4726 }
4727
4728 if (Exchange)
4729 {
4730 sprintf(temp, "cn=%s@mit.edu,%s,%s", before_user_name, contact_ou,
4731 dn_path);
4732
4733 if(rc = ldap_delete_s(ldap_handle, temp))
4734 {
4735 com_err(whoami, 0, "Unable to delete user contact for %s",
4736 user_name);
4737 }
4738
4739 if(contact_create(ldap_handle, dn_path, contact_mail, contact_ou))
4740 {
4741 com_err(whoami, 0, "Unable to create user contact %s", contact_mail);
4742 }
4743 }
4744
4745 name_v[0] = user_name;
4746 sprintf(upn, "%s@%s", user_name, ldap_domain);
4747 userPrincipalName_v[0] = upn;
4748 principal_v[0] = principal;
4749 sprintf(temp, "Kerberos:%s@%s", user_name, PRIMARY_REALM);
4750 sprintf(query_base_dn, "%s%s", ADDRESS_LIST_PREFIX, dn_path);
4751 altSecurityIdentities_v[0] = temp;
4752 samAccountName_v[0] = user_name;
4753 mail_v[0] = mail;
4754 mail_nickname_v[0] = user_name;
4755 proxy_address_v[0] = proxy_address;
4756 query_base_dn_v[0] = query_base_dn;
4757
4758 n = 0;
4759 ADD_ATTR("altSecurityIdentities", altSecurityIdentities_v, LDAP_MOD_REPLACE);
4760 ADD_ATTR("userPrincipalName", userPrincipalName_v, LDAP_MOD_REPLACE);
4761 ADD_ATTR("displayName", name_v, LDAP_MOD_REPLACE);
4762 ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_REPLACE);
4763
4764 if(!ActiveDirectory)
4765 {
4766 ADD_ATTR("uid", samAccountName_v, LDAP_MOD_REPLACE);
4767 ADD_ATTR("eduPersonPrincipalName", mail_v, LDAP_MOD_REPLACE);
4768 ADD_ATTR("displayName", name_v, LDAP_MOD_REPLACE);
4769 ADD_ATTR("eduPersonNickname", name_v, LDAP_MOD_REPLACE);
0ea7f4a0 4770 ADD_ATTR("name", name_v, LDAP_MOD_REPLACE);
61a2844b 4771 }
4772
4773 if (Exchange)
4774 {
4775 ADD_ATTR("msExchQueryBaseDN", query_base_dn_v, LDAP_MOD_REPLACE);
4776 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
4777 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
4778 ADD_ATTR("proxyAddresses", proxy_address_v, LDAP_MOD_REPLACE);
4779 }
4780 else
4781 {
4782 mail_v[0] = contact_mail;
4783 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
08ca7a3e 4784
4785 if(!ActiveDirectory)
4786 {
4787 ADD_ATTR("mitMoiraMail", mail_v, LDAP_MOD_REPLACE);
4788 }
61a2844b 4789 }
4790
4791 mods[n] = NULL;
4792
4793 if(ActiveDirectory)
4794 sprintf(new_dn, "cn=%s,%s,%s", user_name, user_ou, dn_path);
4795 else
4796 sprintf(new_dn, "uid=%s,%s,%s", user_name, user_ou, dn_path);
4797
4798 if ((rc = ldap_modify_s(ldap_handle, new_dn, mods)) != LDAP_SUCCESS)
4799 {
4800 com_err(whoami, 0,
4801 "Unable to modify user data for %s after renaming : %s",
4802 user_name, ldap_err2string(rc));
4803 }
4804
4805 for (i = 0; i < n; i++)
4806 free(mods[i]);
4807
4808 return(rc);
4809}
4810
4811int user_create(int ac, char **av, void *ptr)
4812{
4813 LDAPMod *mods[20];
4814 char new_dn[256];
4815 char user_name[256];
4816 char sam_name[256];
4817 char upn[256];
4818 char mail[256];
4819 char contact_mail[256];
4820 char proxy_address[256];
4821 char mail_nickname[256];
4822 char query_base_dn[256];
4823 char displayName[256];
4824 char address_book[256];
4825 char alt_recipient[256];
4826 char *cn_v[] = {NULL, NULL};
4827 char *objectClass_v[] = {"top", "person", "organizationalPerson",
4828 "user", NULL};
4829 char *objectClass_ldap_v[] = {"top",
4830 "eduPerson", "posixAccount",
4831 "apple-user", "shadowAccount",
4832 "microsoftComTop", "securityPrincipal",
4833 "inetOrgPerson", "user",
4834 "organizationalPerson", "person",
4835 "mailRecipient", NULL};
4836
4837 char *samAccountName_v[] = {NULL, NULL};
4838 char *altSecurityIdentities_v[] = {NULL, NULL};
4839 char *mitMoiraId_v[] = {NULL, NULL};
4840 char *mitMoiraClass_v[] = {NULL, NULL};
4841 char *mitMoiraStatus_v[] = {NULL, NULL};
4842 char *name_v[] = {NULL, NULL};
4843 char *desc_v[] = {NULL, NULL};
4844 char *userPrincipalName_v[] = {NULL, NULL};
4845 char *userAccountControl_v[] = {NULL, NULL};
4846 char *uid_v[] = {NULL, NULL};
4847 char *gid_v[] = {NULL, NULL};
4848 char *mitid_v[] = {NULL, NULL};
4849 char *homedir_v[] = {NULL, NULL};
4850 char *winProfile_v[] = {NULL, NULL};
4851 char *drives_v[] = {NULL, NULL};
4852 char *mail_v[] = {NULL, NULL};
4853 char *givenName_v[] = {NULL, NULL};
4854 char *sn_v[] = {NULL, NULL};
4855 char *initials_v[] = {NULL, NULL};
4856 char *displayName_v[] = {NULL, NULL};
4857 char *proxy_address_v[] = {NULL, NULL};
4858 char *mail_nickname_v[] = {NULL, NULL};
4859 char *query_base_dn_v[] = {NULL, NULL};
4860 char *address_book_v[] = {NULL, NULL};
4861 char *homeMDB_v[] = {NULL, NULL};
4862 char *homeServerName_v[] = {NULL, NULL};
4863 char *mdbUseDefaults_v[] = {NULL, NULL};
4864 char *mailbox_guid_v[] = {NULL, NULL};
4865 char *user_culture_v[] = {NULL, NULL};
4866 char *user_account_control_v[] = {NULL, NULL};
4867 char *msexch_version_v[] = {NULL, NULL};
4868 char *alt_recipient_v[] = {NULL, NULL};
4869 char *hide_address_lists_v[] = {NULL, NULL};
4870 char *principal_v[] = {NULL, NULL};
4871 char *loginshell_v[] = {NULL, NULL};
4872 char userAccountControlStr[80];
4873 char temp[1024];
4874 char principal[256];
4875 char filter_exp[1024];
4876 char search_path[512];
4877 char *attr_array[3];
4878 u_int userAccountControl = UF_NORMAL_ACCOUNT | UF_DONT_EXPIRE_PASSWD |
4879 UF_PASSWD_CANT_CHANGE;
4880 int n;
4881 int rc;
4882 int i;
4883 int OldUseSFU30;
4884 char **call_args;
4885 char WinHomeDir[1024];
4886 char WinProfileDir[1024];
4887 char *homeMDB;
4888 char *homeServerName;
4889 ULONG dwInfo;
4890 char acBERBuf[N_SD_BER_BYTES];
4891 LK_ENTRY *group_base;
4892 int group_count;
4893 char TemplateDn[512];
4894 char TemplateSamName[128];
4895 LDAP_BERVAL **ppsValues;
4896 LDAPControl sControl = {"1.2.840.113556.1.4.801",
4897 { N_SD_BER_BYTES, acBERBuf },
4898 TRUE};
4899 LDAPControl *apsServerControls[] = {&sControl, NULL};
4900 LDAPMessage *psMsg;
4901 char *argv[3];
4902 char *save_argv[7];
4903 char search_string[256];
4904 char *o_v[] = {NULL, NULL};
4905 char *p, *q;
4906 char *mail_routing_v[] = {NULL, NULL};
4907 char *c;
4908
4909 call_args = ptr;
4910
4911 dwInfo = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
4912 DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION;
4913 BEREncodeSecurityBits(dwInfo, acBERBuf);
4914
4915 if (!check_string(av[U_NAME]))
4916 {
4917 callback_rc = AD_INVALID_NAME;
4918 com_err(whoami, 0, "Unable to process invalid LDAP user name %s",
4919 av[U_NAME]);
4920 return(AD_INVALID_NAME);
4921 }
4922
4923 memset(WinHomeDir, '\0', sizeof(WinHomeDir));
4924 memset(WinProfileDir, '\0', sizeof(WinProfileDir));
4925 memset(displayName, '\0', sizeof(displayName));
4926 memset(query_base_dn, '\0', sizeof(query_base_dn));
4927 strcpy(WinHomeDir, av[U_WINHOMEDIR]);
4928 strcpy(WinProfileDir, av[U_WINPROFILEDIR]);
4929 strcpy(user_name, av[U_NAME]);
4930 sprintf(upn, "%s@%s", user_name, ldap_domain);
4931 sprintf(sam_name, "%s", av[U_NAME]);
4932
4933 if(strlen(av[U_FIRST])) {
4934 strcat(displayName, av[U_FIRST]);
4935 }
4936
4937 if(strlen(av[U_MIDDLE])) {
4938 if(strlen(av[U_FIRST]))
4939 strcat(displayName, " ");
4940
4941 strcat(displayName, av[U_MIDDLE]);
4942 }
4943
4944 if(strlen(av[U_LAST])) {
4945 if(strlen(av[U_FIRST]) || strlen(av[U_MIDDLE]))
4946 strcat(displayName, " ");
4947
4948 strcat(displayName, av[U_LAST]);
4949 }
4950
4951 samAccountName_v[0] = sam_name;
4952 if ((atoi(av[U_STATE]) != US_NO_PASSWD) &&
4953 (atoi(av[U_STATE]) != US_REGISTERED))
4954 {
4955 userAccountControl |= UF_ACCOUNTDISABLE;
4956
4957 if (Exchange)
4958 {
4959 hide_address_lists_v[0] = "TRUE";
4960 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
4961 LDAP_MOD_ADD);
4962 }
4963 }
4964
4965 sprintf(userAccountControlStr, "%ld", userAccountControl);
4966 userAccountControl_v[0] = userAccountControlStr;
4967 userPrincipalName_v[0] = upn;
4968
4969 if(ActiveDirectory)
4970 cn_v[0] = user_name;
4971 else
4972 cn_v[0] = displayName;
4973
4974 name_v[0] = user_name;
4975 desc_v[0] = "Auto account created by Moira";
4976 mail_v[0] = mail;
4977 givenName_v[0] = av[U_FIRST];
4978
4979 if(ActiveDirectory)
4980 sn_v[0] = av[U_LAST];
4981 else
4982 if(strlen(av[U_LAST]))
4983 sn_v[0] = av[U_LAST];
4984 else
4985 sn_v[0] = av[U_NAME];
4986
4987 displayName_v[0] = displayName;
4988 mail_nickname_v[0] = user_name;
4989 o_v[0] = "Massachusetts Institute of Technology";
4990
4991 sprintf(temp, "Kerberos:%s@%s", user_name, PRIMARY_REALM);
4992 sprintf(principal, "%s@%s", user_name, PRIMARY_REALM);
4993 altSecurityIdentities_v[0] = temp;
4994 principal_v[0] = principal;
4995
4996 if(ActiveDirectory)
4997 sprintf(new_dn, "cn=%s,%s,%s", user_name, user_ou, call_args[1]);
4998 else
4999 sprintf(new_dn, "uid=%s,%s,%s", user_name, user_ou, call_args[1]);
5000
5001 sprintf(mail,"%s@%s", user_name, lowercase(ldap_domain));
5002 sprintf(contact_mail, "%s@mit.edu", user_name);
5003 sprintf(query_base_dn, "%s%s", ADDRESS_LIST_PREFIX, call_args[1]);
5004 query_base_dn_v[0] = query_base_dn;
5005 sprintf(alt_recipient, "cn=%s@mit.edu,%s,%s", user_name, contact_ou,
5006 call_args[1]);
5007 sprintf(search_string, "@%s", uppercase(ldap_domain));
5008
5009 if (Exchange)
5010 {
5011 if(contact_create((LDAP *)call_args[0], call_args[1], contact_mail,
5012 contact_ou))
5013 {
5014 com_err(whoami, 0, "Unable to create user contact %s",
5015 contact_mail);
5016 }
5017
5018 if(find_homeMDB((LDAP *)call_args[0], call_args[1], &homeMDB,
5019 &homeServerName))
5020 {
5021 com_err(whoami, 0, "Unable to locate homeMB and homeServerName");
5022 return(1);
5023 }
5024
5025 com_err(whoami, 0, "homeMDB:%s", homeMDB);
5026 com_err(whoami, 0, "homeServerName:%s", homeServerName);
5027
5028 homeMDB_v[0] = homeMDB;
5029 homeServerName_v[0] = homeServerName;
5030 }
5031
5032 n = 0;
5033
5034 ADD_ATTR("cn", cn_v, LDAP_MOD_ADD);
5035
5036 if(ActiveDirectory)
5037 {
5038 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
5039 }
5040 else
5041 {
5042 ADD_ATTR("objectClass", objectClass_ldap_v, LDAP_MOD_ADD);
5043 }
5044
5045 ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_ADD);
5046 ADD_ATTR("userPrincipalName", userPrincipalName_v, LDAP_MOD_ADD);
5047 ADD_ATTR("userAccountControl", userAccountControl_v, LDAP_MOD_ADD);
5048 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
5049 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
5050
5051 if (Exchange)
5052 {
5053 ADD_ATTR("msExchQueryBaseDN", query_base_dn_v, LDAP_MOD_ADD);
5054 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_ADD);
5055 ADD_ATTR("homeMDB", homeMDB_v, LDAP_MOD_ADD);
5056 mdbUseDefaults_v[0] = "TRUE";
5057 ADD_ATTR("mdbUseDefaults", mdbUseDefaults_v, LDAP_MOD_ADD);
5058 ADD_ATTR("msExchHomeServerName", homeServerName_v, LDAP_MOD_ADD);
5059
5060 argv[0] = user_name;
5061
5062 if (!(rc = mr_query("get_pobox", 1, argv, save_query_info, save_argv)))
5063 {
5064 if(!strcmp(save_argv[1], "EXCHANGE") ||
5065 (strstr(save_argv[3], search_string) != NULL))
5066 {
5067 argv[0] = exchange_acl;
5068 argv[1] = "USER";
5069 argv[2] = user_name;
5070
5071 rc = mr_query("add_member_to_list", 3, argv, NULL, NULL);
5072
5073 if ((rc) && (rc != MR_EXISTS))
5074 {
5075 com_err(whoami, 0, "Unable to add user %s to %s: %s",
5076 user_name, exchange_acl, error_message(rc));
5077 }
5078 }
5079 else
5080 {
5081 alt_recipient_v[0] = alt_recipient;
5082 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_ADD);
5083 }
5084 }
5085 else
5086 {
5087 alt_recipient_v[0] = alt_recipient;
5088 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_ADD);
5089
5090 com_err(whoami, 0, "Unable to fetch pobox for %s", user_name);
5091 }
5092 }
5093 else
5094 {
5095 mail_v[0] = contact_mail;
5096 ADD_ATTR("mail", mail_v, LDAP_MOD_ADD);
08ca7a3e 5097
5098 if(!ActiveDirectory)
5099 {
5100 ADD_ATTR("mitMoiraMail", mail_v, LDAP_MOD_ADD);
5101 }
61a2844b 5102 }
5103
5104 if(strlen(av[U_FIRST])) {
5105 ADD_ATTR("givenName", givenName_v, LDAP_MOD_ADD);
5106 }
5107
5108 if(strlen(av[U_LAST]) || strlen(av[U_NAME])) {
5109 ADD_ATTR("sn", sn_v, LDAP_MOD_ADD);
5110 }
5111
5112 if(strlen(av[U_FIRST]) || strlen(av[U_MIDDLE]) || strlen(av[U_LAST])) {
5113 ADD_ATTR("displayName", displayName_v, LDAP_MOD_ADD);
5114
5115 if(!ActiveDirectory)
5116 {
5117 ADD_ATTR("eduPersonNickname", displayName_v, LDAP_MOD_ADD);
5118 }
5119 } else {
5120 ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
5121
5122 if(!ActiveDirectory)
5123 {
5124 ADD_ATTR("eduPersonNickname", name_v, LDAP_MOD_ADD);
5125 }
5126 }
5127
5128 if (strlen(av[U_MIDDLE]) == 1) {
5129 initials_v[0] = av[U_MIDDLE];
5130 ADD_ATTR("initials", initials_v, LDAP_MOD_ADD);
5131 }
5132
5133 if (strlen(call_args[2]) != 0)
5134 {
5135 mitMoiraId_v[0] = call_args[2];
5136 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_ADD);
5137 }
5138
5139 ADD_ATTR("altSecurityIdentities", altSecurityIdentities_v, LDAP_MOD_ADD);
5140
5141 if(!ActiveDirectory)
5142 {
5143 loginshell_v[0] = av[U_SHELL];
5144 mitMoiraClass_v[0] = av[U_CLASS];
5145 mitMoiraStatus_v[0] = av[U_STATE];
5146 ADD_ATTR("loginShell", loginshell_v, LDAP_MOD_ADD);
5147 ADD_ATTR("uid", samAccountName_v, LDAP_MOD_ADD);
5148 ADD_ATTR("eduPersonPrincipalName", mail_v, LDAP_MOD_ADD);
5149 ADD_ATTR("o", o_v, LDAP_MOD_ADD);
5150 ADD_ATTR("mitMoiraClass", mitMoiraClass_v, LDAP_MOD_ADD);
5151 ADD_ATTR("mitMoiraStatus", mitMoiraStatus_v, LDAP_MOD_ADD);
5152 }
5153
5154 if (strlen(av[U_UID]) != 0)
5155 {
5156 uid_v[0] = av[U_UID];
5157
5158 if(ActiveDirectory)
5159 {
5160 ADD_ATTR("uid", uid_v, LDAP_MOD_ADD);
5161 }
5162 else
5163 {
5164 gid_v[0] = "101";
5165 ADD_ATTR("uidNumber", uid_v, LDAP_MOD_ADD);
5166 ADD_ATTR("gidNumber", gid_v, LDAP_MOD_ADD);
5167 }
5168
5169 if(ActiveDirectory)
5170 {
5171 if (!UseSFU30)
5172 {
5173 ADD_ATTR("uidNumber", uid_v, LDAP_MOD_ADD);
5174 }
5175 else
5176 {
5177 ADD_ATTR("msSFU30UidNumber", uid_v, LDAP_MOD_ADD);
5178 }
5179 }
5180 }
5181
5182 if ((strlen(av[U_MITID]) != 0) && (av[U_MITID][0] == '9'))
5183 mitid_v[0] = av[U_MITID];
5184 else
5185 mitid_v[0] = "none";
5186
5187 ADD_ATTR("employeeID", mitid_v, LDAP_MOD_ADD);
5188
5189 n = SetHomeDirectory((LDAP *)call_args[0], user_name, new_dn,
5190 WinHomeDir, WinProfileDir, homedir_v, winProfile_v,
5191 drives_v, mods, LDAP_MOD_ADD, n);
5192
5193 if(ActiveDirectory)
5194 {
5195 sprintf(filter_exp, "(sAMAccountName=%s)", "UserTemplate.u");
5196 sprintf(search_path, "%s,%s", security_template_ou, call_args[1]);
5197 attr_array[0] = "sAMAccountName";
5198 attr_array[1] = NULL;
5199 group_count = 0;
5200 group_base = NULL;
5201
5202 if ((rc = linklist_build((LDAP *)call_args[0], search_path, filter_exp,
5203 attr_array, &group_base, &group_count,
5204 LDAP_SCOPE_SUBTREE) != 0))
5205 return(1);
5206
5207 if (group_count != 1)
5208 {
5209 com_err(whoami, 0, "Unable to process user security template: %s - "
5210 "security not set", "UserTemplate.u");
5211 return(1);
5212 }
5213
5214 strcpy(TemplateDn, group_base->dn);
5215 strcpy(TemplateSamName, group_base->value);
5216 linklist_free(group_base);
5217 group_base = NULL;
5218 group_count = 0;
5219
5220 rc = ldap_search_ext_s((LDAP *)call_args[0], search_path,
5221 LDAP_SCOPE_SUBTREE, filter_exp, NULL, 0,
5222 apsServerControls, NULL,
5223 NULL, 0, &psMsg);
5224
5225 if ((psMsg = ldap_first_entry((LDAP *)call_args[0], psMsg)) == NULL)
5226 {
5227 com_err(whoami, 0, "Unable to find user security template: %s - "
5228 "security not set", "UserTemplate.u");
5229 return(1);
5230 }
5231
5232 ppsValues = ldap_get_values_len((LDAP *)call_args[0], psMsg,
5233 "ntSecurityDescriptor");
5234 if (ppsValues == NULL)
5235 {
5236 com_err(whoami, 0, "Unable to find user security template: %s - "
5237 "security not set", "UserTemplate.u");
5238 return(1);
5239 }
5240
5241 ADD_ATTR("ntSecurityDescriptor", (char **)ppsValues,
5242 LDAP_MOD_REPLACE | LDAP_MOD_BVALUES);
5243 }
5244
5245 mods[n] = NULL;
5246
5247 rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL);
5248
5249 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
5250 {
5251 OldUseSFU30 = UseSFU30;
5252 SwitchSFU(mods, &UseSFU30, n);
5253 if (OldUseSFU30 != UseSFU30)
5254 rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL);
5255 }
5256
5257 for (i = 0; i < n; i++)
5258 free(mods[i]);
5259
5260 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
5261 {
5262 com_err(whoami, 0, "Unable to create user %s : %s",
5263 user_name, ldap_err2string(rc));
5264 callback_rc = rc;
5265 return(rc);
5266 }
5267
5268 if ((rc == LDAP_SUCCESS) && (SetPassword))
5269 {
5270 if ((rc = set_password(sam_name, "", ldap_domain)) != 0)
5271 {
5272 ad_kdc_disconnect();
5273 if (!ad_server_connect(default_server, ldap_domain))
5274 {
5275 com_err(whoami, 0, "Unable to set password for user %s : %s",
5276 user_name,
5277 "cannot get changepw ticket from windows domain");
5278 }
5279 else
5280 {
5281 if ((rc = set_password(sam_name, "", ldap_domain)) != 0)
5282 {
5283 com_err(whoami, 0, "Unable to set password for user %s "
5284 ": %ld", user_name, rc);
5285 }
5286 }
5287 }
5288 }
5289
5290 if(!ActiveDirectory)
5291 {
5292 if (rc = moira_connect())
5293 {
c9ef9269 5294 critical_alert("Ldap incremental",
61a2844b 5295 "Error contacting Moira server : %s",
5296 error_message(rc));
5297 return;
5298 }
5299
5300 argv[0] = user_name;
5301
5302 if (!(rc = mr_query("get_pobox", 1, argv, save_query_info, save_argv)))
5303 {
0384092e 5304 n = 0;
5305 ADD_ATTR("mailRoutingAddress", mail_routing_v, LDAP_MOD_REPLACE);
5306 mods[n] = NULL;
5307 rc = ldap_modify_s((LDAP *)call_args[0], new_dn, mods);
5308
5309 if (rc == LDAP_ALREADY_EXISTS || rc == LDAP_TYPE_OR_VALUE_EXISTS)
5310 rc = LDAP_SUCCESS;
5311
5312 if(rc)
5313 com_err(whoami, 0,
5314 "Unable to set the mailRoutingAddress for %s : %s",
5315 user_name, ldap_err2string(rc));
5316
61a2844b 5317 p = strdup(save_argv[3]);
5318
5319 if((c = strchr(p, ',')) != NULL) {
5320 q = strtok(p, ",");
5321 StringTrim(q);
5322
5323 if ((c = strchr(q, '@')) == NULL)
5324 sprintf(temp, "%s@mit.edu", q);
5325 else
5326 sprintf(temp, "%s", q);
5327
5328 if(email_isvalid(temp) && atoi(av[U_STATE]) != US_DELETED)
5329 {
5330 mail_routing_v[0] = temp;
5331
5332 n = 0;
5333 ADD_ATTR("mailRoutingAddress", mail_routing_v, LDAP_MOD_ADD);
5334 mods[n] = NULL;
5335 rc = ldap_modify_s((LDAP *)call_args[0], new_dn, mods);
5336
5337 if (rc == LDAP_ALREADY_EXISTS ||
5338 rc == LDAP_TYPE_OR_VALUE_EXISTS)
5339 rc = LDAP_SUCCESS;
5340
5341 if(rc)
5342 com_err(whoami, 0,
5343 "Unable to set the mailRoutingAddress for %s : %s",
5344 user_name, ldap_err2string(rc));
5345 }
5346
5347 while((q = strtok(NULL, ",")) != NULL) {
5348 StringTrim(q);
5349
5350 if((c = strchr(q, '@')) == NULL)
5351 sprintf(temp, "%s@mit.edu", q);
5352 else
5353 sprintf(temp, "%s", q);
5354
5355 if(email_isvalid(temp) && atoi(av[U_STATE]) != US_DELETED)
5356 {
5357 mail_routing_v[0] = temp;
5358
5359 n = 0;
5360 ADD_ATTR("mailRoutingAddress", mail_routing_v, LDAP_MOD_ADD);
5361 mods[n] = NULL;
5362 rc = ldap_modify_s((LDAP *)call_args[0], new_dn, mods);
5363
5364 if (rc == LDAP_ALREADY_EXISTS ||
5365 rc == LDAP_TYPE_OR_VALUE_EXISTS)
5366 rc = LDAP_SUCCESS;
5367
5368 if(rc)
5369 com_err(whoami, 0,
5370 "Unable to set the mailRoutingAddress for %s : %s",
5371 user_name, ldap_err2string(rc));
5372 }
5373 }
5374 } else {
5375 StringTrim(p);
5376
5377 if((c = strchr(p, '@')) == NULL)
5378 sprintf(temp, "%s@mit.edu", p);
5379 else
5380 sprintf(temp, "%s", p);
5381
5382 if(email_isvalid(temp) && atoi(av[U_STATE]) != US_DELETED)
5383 {
5384 mail_routing_v[0] = temp;
5385
5386 n = 0;
5387 ADD_ATTR("mailRoutingAddress", mail_routing_v, LDAP_MOD_ADD);
5388 mods[n] = NULL;
5389 rc = ldap_modify_s((LDAP *)call_args[0], new_dn, mods);
5390
5391 if (rc == LDAP_ALREADY_EXISTS ||
5392 rc == LDAP_TYPE_OR_VALUE_EXISTS)
5393 rc = LDAP_SUCCESS;
5394
5395 if(rc)
5396 com_err(whoami, 0,
5397 "Unable to set the mailRoutingAddress for %s : %s",
5398 user_name, ldap_err2string(rc));
5399 }
5400 }
5401 }
5402 moira_disconnect();
5403 }
5404
5405 return(0);
5406}
5407
5408int user_change_status(LDAP *ldap_handle, char *dn_path,
5409 char *user_name, char *MoiraId,
5410 int operation)
5411{
5412 char filter[128];
5413 char *attr_array[3];
5414 char temp[256];
5415 char distinguished_name[1024];
5416 char **modvalues;
5417 char *mitMoiraId_v[] = {NULL, NULL};
5418 LDAPMod *mods[20];
5419 LK_ENTRY *group_base;
5420 int group_count;
5421 int rc;
5422 int i;
5423 int n;
5424 ULONG ulongValue;
5425
5426 if (!check_string(user_name))
5427 {
5428 com_err(whoami, 0, "Unable to process invalid LDAP user name %s",
5429 user_name);
5430 return(AD_INVALID_NAME);
5431 }
5432
5433 group_count = 0;
5434 group_base = NULL;
5435
5436 if (strlen(MoiraId) != 0)
5437 {
5438 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
5439 attr_array[0] = "UserAccountControl";
5440 attr_array[1] = NULL;
5441 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5442 &group_base, &group_count,
5443 LDAP_SCOPE_SUBTREE)) != 0)
5444 {
5445 com_err(whoami, 0, "Unable to process user %s : %s",
5446 user_name, ldap_err2string(rc));
5447 return(rc);
5448 }
5449 }
5450
5451 if (group_count != 1)
5452 {
5453 linklist_free(group_base);
5454 group_count = 0;
5455 group_base = NULL;
5456 sprintf(filter, "(sAMAccountName=%s)", user_name);
5457 attr_array[0] = "UserAccountControl";
5458 attr_array[1] = NULL;
5459 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5460 &group_base, &group_count,
5461 LDAP_SCOPE_SUBTREE)) != 0)
5462 {
5463 com_err(whoami, 0, "Unable to process user %s : %s",
5464 user_name, ldap_err2string(rc));
5465 return(rc);
5466 }
5467 }
5468
5469 if (group_count != 1)
5470 {
5471 linklist_free(group_base);
c9ef9269 5472 com_err(whoami, 0, "Unable to find user %s in directory",
61a2844b 5473 user_name);
5474 return(LDAP_NO_SUCH_OBJECT);
5475 }
5476
5477 strcpy(distinguished_name, group_base->dn);
5478 ulongValue = atoi((*group_base).value);
5479
5480 if (operation == MEMBER_DEACTIVATE)
5481 ulongValue |= UF_ACCOUNTDISABLE;
5482 else
5483 ulongValue &= ~UF_ACCOUNTDISABLE;
5484
5485 sprintf(temp, "%ld", ulongValue);
5486
5487 if ((rc = construct_newvalues(group_base, group_count, (*group_base).value,
5488 temp, &modvalues, REPLACE)) == 1)
5489 goto cleanup;
5490
5491 linklist_free(group_base);
5492 group_base = NULL;
5493 group_count = 0;
5494 n = 0;
5495 ADD_ATTR("UserAccountControl", modvalues, LDAP_MOD_REPLACE);
5496
5497 if (strlen(MoiraId) != 0)
5498 {
5499 mitMoiraId_v[0] = MoiraId;
5500 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_REPLACE);
5501 }
5502
5503 mods[n] = NULL;
5504 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
5505
5506 for (i = 0; i < n; i++)
5507 free(mods[i]);
5508
5509 free_values(modvalues);
5510
5511 if (rc != LDAP_SUCCESS)
5512 {
5513 com_err(whoami, 0, "Unable to change status of user %s : %s",
5514 user_name, ldap_err2string(rc));
5515 }
5516
5517 cleanup:
5518 return(rc);
5519}
5520
5521int user_delete(LDAP *ldap_handle, char *dn_path,
5522 char *u_name, char *MoiraId)
5523{
5524 char filter[128];
5525 char *attr_array[3];
5526 char distinguished_name[1024];
5527 char user_name[512];
5528 LK_ENTRY *group_base;
5529 int group_count;
5530 int rc;
5531 char temp[256];
5532
5533 if (!check_string(u_name))
5534 return(AD_INVALID_NAME);
5535
5536 strcpy(user_name, u_name);
5537 group_count = 0;
5538 group_base = NULL;
5539
5540 if (strlen(MoiraId) != 0)
5541 {
5542 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
5543 attr_array[0] = "name";
5544 attr_array[1] = NULL;
5545 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5546 &group_base, &group_count,
5547 LDAP_SCOPE_SUBTREE)) != 0)
5548 {
5549 com_err(whoami, 0, "Unable to process user %s : %s",
5550 user_name, ldap_err2string(rc));
5551 goto cleanup;
5552 }
5553 }
5554
5555 if (group_count != 1)
5556 {
5557 linklist_free(group_base);
5558 group_count = 0;
5559 group_base = NULL;
5560 sprintf(filter, "(sAMAccountName=%s)", user_name);
5561 attr_array[0] = "name";
5562 attr_array[1] = NULL;
5563 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5564 &group_base, &group_count,
5565 LDAP_SCOPE_SUBTREE)) != 0)
5566 {
5567 com_err(whoami, 0, "Unable to process user %s : %s",
5568 user_name, ldap_err2string(rc));
5569 goto cleanup;
5570 }
5571 }
5572
5573 if (group_count != 1)
5574 {
61a2844b 5575 goto cleanup;
5576 }
5577
5578 strcpy(distinguished_name, group_base->dn);
5579
5580 if (rc = ldap_delete_s(ldap_handle, distinguished_name))
5581 {
5582 com_err(whoami, 0, "Unable to process user %s : %s",
5583 user_name, ldap_err2string(rc));
5584 }
5585
5586 /* Need to add code to delete mit.edu contact */
5587
5588 if (Exchange)
5589 {
5590 sprintf(temp, "cn=%s@mit.edu,%s,%s", user_name, contact_ou, dn_path);
5591
5592 if(rc = ldap_delete_s(ldap_handle, temp))
5593 {
5594 com_err(whoami, 0, "Unable to delete user contact for %s",
5595 user_name);
5596 }
5597 }
5598
5599 cleanup:
5600 linklist_free(group_base);
5601
5602 return(0);
5603}
5604
5605void linklist_free(LK_ENTRY *linklist_base)
5606{
5607 LK_ENTRY *linklist_previous;
5608
5609 while (linklist_base != NULL)
5610 {
5611 if (linklist_base->dn != NULL)
5612 free(linklist_base->dn);
5613
5614 if (linklist_base->attribute != NULL)
5615 free(linklist_base->attribute);
5616
5617 if (linklist_base->value != NULL)
5618 free(linklist_base->value);
5619
5620 if (linklist_base->member != NULL)
5621 free(linklist_base->member);
5622
5623 if (linklist_base->type != NULL)
5624 free(linklist_base->type);
5625
5626 if (linklist_base->list != NULL)
5627 free(linklist_base->list);
5628
5629 linklist_previous = linklist_base;
5630 linklist_base = linklist_previous->next;
5631 free(linklist_previous);
5632 }
5633}
5634
5635void free_values(char **modvalues)
5636{
5637 int i;
5638
5639 i = 0;
5640
5641 if (modvalues != NULL)
5642 {
5643 while (modvalues[i] != NULL)
5644 {
5645 free(modvalues[i]);
5646 modvalues[i] = NULL;
5647 ++i;
5648 }
5649 free(modvalues);
5650 }
5651}
5652
5653static int illegalchars[] = {
5654 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^@ - ^O */
5655 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^P - ^_ */
5656 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, /* SPACE - / */
5657 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, /* 0 - ? */
5658 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* @ - O */
5659 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, /* P - _ */
5660 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ` - o */
5661 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, /* p - ^? */
5662 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5663 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5664 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5665 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5666 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5667 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5668 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5669 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5670};
5671
5672static int illegalchars_ldap[] = {
5673 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^@ - ^O */
5674 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^P - ^_ */
a0407f40 5675 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, /* SPACE - / */
61a2844b 5676 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, /* 0 - ? */
5677 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* @ - O */
5678 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, /* P - _ */
5679 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ` - o */
5680 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, /* p - ^? */
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 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5684 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5685 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5686 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5687 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5688 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5689};
5690
5691int check_string(char *s)
5692{
5693 char character;
b6e441c5 5694 char *string;
5695
5696 string = s;
61a2844b 5697
5698 for (; *s; s++)
5699 {
5700 character = *s;
5701
5702 if (isupper(character))
5703 character = tolower(character);
5704
5705 if(ActiveDirectory)
5706 {
5707 if (illegalchars[(unsigned) character])
a0407f40 5708 {
5709 com_err(whoami, 0, "Found illegal char '%c' (%d) in string %s",
b6e441c5 5710 character, (unsigned) character, string);
a0407f40 5711 return 0;
5712 }
61a2844b 5713 }
5714 else
5715 {
5716 if (illegalchars_ldap[(unsigned) character])
a0407f40 5717 {
5718 com_err(whoami, 0, "Found illegal char '%c' (%d) in string %s",
b6e441c5 5719 character, (unsigned) character, string);
a0407f40 5720 return 0;
5721 }
61a2844b 5722 }
5723 }
5724
5725 return(1);
5726}
5727
5728int check_container_name(char *s)
5729{
5730 char character;
5731
5732 for (; *s; s++)
5733 {
5734 character = *s;
5735
5736 if (isupper(character))
5737 character = tolower(character);
5738
5739 if (character == ' ')
5740 continue;
5741
5742 if (illegalchars[(unsigned) character])
5743 return 0;
5744 }
5745
5746 return(1);
5747}
5748
5749int mr_connect_cl(char *server, char *client, int version, int auth)
5750{
5751 int status;
5752 char *motd;
5753 char temp[128];
5754
5755 status = mr_connect(server);
5756
5757 if (status)
5758 {
5759 com_err(whoami, status, "while connecting to Moira");
5760 return status;
5761 }
5762
5763 status = mr_motd(&motd);
5764
5765 if (status)
5766 {
5767 mr_disconnect();
5768 com_err(whoami, status, "while checking server status");
5769 return status;
5770 }
5771
5772 if (motd)
5773 {
5774 sprintf(temp, "The Moira server is currently unavailable: %s", motd);
5775 com_err(whoami, status, temp);
5776 mr_disconnect();
5777 return status;
5778 }
5779
5780 status = mr_version(version);
5781
5782 if (status)
5783 {
5784 if (status == MR_UNKNOWN_PROC)
5785 {
5786 if (version > 2)
5787 status = MR_VERSION_HIGH;
5788 else
5789 status = MR_SUCCESS;
5790 }
5791
5792 if (status == MR_VERSION_HIGH)
5793 {
5794 com_err(whoami, 0, "Warning: This client is running newer code "
5795 "than the server.");
5796 com_err(whoami, 0, "Some operations may not work.");
5797 }
5798 else if (status && status != MR_VERSION_LOW)
5799 {
5800 com_err(whoami, status, "while setting query version number.");
5801 mr_disconnect();
5802 return status;
5803 }
5804 }
5805
5806 if (auth)
5807 {
5808 status = mr_krb5_auth(client);
5809 if (status)
5810 {
5811 com_err(whoami, status, "while authenticating to Moira.");
5812 mr_disconnect();
5813 return status;
5814 }
5815 }
5816
5817 return MR_SUCCESS;
5818}
5819
5820void AfsToWinAfs(char* path, char* winPath)
5821{
5822 char* pathPtr;
5823 char* winPathPtr;
5824 strcpy(winPath, WINAFS);
5825 pathPtr = path + strlen(AFS);
5826 winPathPtr = winPath + strlen(WINAFS);
5827
5828 while (*pathPtr)
5829 {
5830 if (*pathPtr == '/')
5831 *winPathPtr = '\\';
5832 else
5833 *winPathPtr = *pathPtr;
5834
5835 pathPtr++;
5836 winPathPtr++;
5837 }
5838}
5839
5840int GetAceInfo(int ac, char **av, void *ptr)
5841{
5842 char **call_args;
5843 int security_flag;
5844
5845 call_args = ptr;
5846
5847 strcpy(call_args[0], av[L_ACE_TYPE]);
5848 strcpy(call_args[1], av[L_ACE_NAME]);
5849 security_flag = 0;
5850 get_group_membership(call_args[2], call_args[3], &security_flag, av);
5851 return(LDAP_SUCCESS);
5852}
5853
5854int checkADname(LDAP *ldap_handle, char *dn_path, char *Name)
5855{
5856 char filter[128];
5857 char *attr_array[3];
5858 int group_count;
5859 int rc;
5860 LK_ENTRY *group_base;
5861
5862 group_count = 0;
5863 group_base = NULL;
5864
5865 sprintf(filter, "(sAMAccountName=%s)", Name);
5866 attr_array[0] = "sAMAccountName";
5867 attr_array[1] = NULL;
5868
5869 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5870 &group_base, &group_count,
5871 LDAP_SCOPE_SUBTREE)) != 0)
5872 {
5873 com_err(whoami, 0, "Unable to process ACE name %s : %s",
5874 Name, ldap_err2string(rc));
5875 return(1);
5876 }
5877
5878 linklist_free(group_base);
5879 group_base = NULL;
5880
5881 if (group_count == 0)
5882 return(0);
5883
5884 return(1);
5885}
5886
5887#define MAX_ACE 7
5888
5889int ProcessAce(LDAP *ldap_handle, char *dn_path, char *Name, char *Type,
5890 int UpdateGroup, int *ProcessGroup, char *maillist)
5891{
5892 char *av[2];
5893 char GroupName[256];
5894 char *call_args[7];
5895 int rc;
5896 char *AceInfo[4];
5897 char AceType[32];
5898 char AceName[128];
5899 char AceMembership[2];
5900 char AceOu[256];
5901 char temp[128];
5902 char *save_argv[U_END];
5903
5904 if (!SetGroupAce)
5905 {
5906 com_err(whoami, 0, "ProcessAce disabled, skipping");
5907 return(0);
5908 }
5909
5910 strcpy(GroupName, Name);
5911
5912 if (strcasecmp(Type, "LIST"))
5913 return(1);
5914
5915 while (1)
5916 {
5917 av[0] = GroupName;
5918 AceInfo[0] = AceType;
5919 AceInfo[1] = AceName;
5920 AceInfo[2] = AceMembership;
5921 AceInfo[3] = AceOu;
5922 memset(AceType, '\0', sizeof(AceType));
5923 memset(AceName, '\0', sizeof(AceName));
5924 memset(AceMembership, '\0', sizeof(AceMembership));
5925 memset(AceOu, '\0', sizeof(AceOu));
5926 callback_rc = 0;
5927
5928 if (rc = mr_query("get_list_info", 1, av, GetAceInfo, AceInfo))
5929 {
a0407f40 5930 if(rc != MR_NO_MATCH)
a2aa35d9 5931 com_err(whoami, 0, "Unable to get ACE info for list %s : %s",
5932 GroupName, error_message(rc));
5933
61a2844b 5934 return(1);
5935 }
5936
5937 if (callback_rc)
5938 {
5939 com_err(whoami, 0, "Unable to get ACE info for list %s", GroupName);
5940 return(1);
5941 }
5942
5943 if ((strcasecmp(AceType, "USER")) && (strcasecmp(AceType, "LIST")))
5944 return(0);
5945
5946 strcpy(temp, AceName);
5947
5948 if (!strcasecmp(AceType, "LIST"))
5949 sprintf(temp, "%s%s", AceName, group_suffix);
5950
5951 if (!UpdateGroup)
5952 {
5953 if (checkADname(ldap_handle, dn_path, temp))
5954 return(0);
5955
5956 (*ProcessGroup) = 1;
5957 }
5958
5959 if (!strcasecmp(AceInfo[0], "LIST"))
5960 {
5961 if (make_new_group(ldap_handle, dn_path, "", AceName, AceOu,
5962 AceMembership, 0, UpdateGroup, maillist))
5963 return(1);
33448741 5964
5965 populate_group(ldap_handle, dn_path, AceName, AceOu, AceMembership,
5966 0, "");
61a2844b 5967 }
5968 else if (!strcasecmp(AceInfo[0], "USER"))
5969 {
5970 av[0] = AceName;
5971 call_args[0] = (char *)ldap_handle;
5972 call_args[1] = dn_path;
5973 call_args[2] = "";
5974 call_args[3] = NULL;
5975 callback_rc = 0;
5976
7c22be37 5977 if(!strcasecmp(AceName, PRODUCTION_PRINCIPAL) ||
5978 !strcasecmp(AceName, TEST_PRINCIPAL))
5979 {
5980 return(1);
5981 }
5982
61a2844b 5983 if (rc = mr_query("get_user_account_by_login", 1, av,
5984 save_query_info, save_argv))
5985 {
5986 com_err(whoami, 0, "Unable to process user ACE %s for group %s.",
5987 AceName, Name);
5988 return(1);
5989 }
5990
5991 if (rc = user_create(U_END, save_argv, call_args))
5992 {
5993 com_err(whoami, 0, "Unable to process user ACE %s for group %s.",
5994 AceName, Name);
5995 return(1);
5996 }
5997
5998 if (callback_rc)
5999 {
6000 com_err(whoami, 0, "Unable to process user Ace %s for group %s",
6001 AceName, Name);
6002 return(1);
6003 }
6004
6005 return(0);
6006 }
6007 else
6008 return(1);
6009
6010 if (!strcasecmp(AceType, "LIST"))
6011 {
6012 if (!strcasecmp(GroupName, AceName))
6013 return(0);
6014 }
6015
6016 strcpy(GroupName, AceName);
6017 }
6018
6019 return(1);
6020}
6021
6022int make_new_group(LDAP *ldap_handle, char *dn_path, char *MoiraId,
6023 char *group_name, char *group_ou, char *group_membership,
6024 int group_security_flag, int updateGroup, char *maillist)
6025{
6026 char *av[3];
6027 char *call_args[8];
6028 int rc;
6029 LK_ENTRY *group_base;
6030 int group_count;
6031 char filter[128];
6032 char *attr_array[3];
6033
6034 av[0] = group_name;
6035 call_args[0] = (char *)ldap_handle;
6036 call_args[1] = dn_path;
6037 call_args[2] = group_name;
6038 call_args[3] = (char *)(MOIRA_USERS | MOIRA_KERBEROS | MOIRA_STRINGS);
6039 call_args[4] = (char *)updateGroup;
6040 call_args[5] = MoiraId;
6041 call_args[6] = "0";
6042 call_args[7] = NULL;
6043 callback_rc = 0;
6044
6045 group_count = 0;
6046 group_base = NULL;
6047
6048 if (rc = mr_query("get_list_info", 1, av, group_create, call_args))
6049 {
6050 moira_disconnect();
6051 com_err(whoami, 0, "Unable to create list %s : %s", group_name,
6052 error_message(rc));
6053 return(rc);
6054 }
6055
6056 if (callback_rc)
6057 {
6058 moira_disconnect();
6059 com_err(whoami, 0, "Unable to create list %s", group_name);
6060 return(callback_rc);
6061 }
6062
6063 return(0);
6064}
6065
6066int populate_group(LDAP *ldap_handle, char *dn_path, char *group_name,
6067 char *group_ou, char *group_membership,
6068 int group_security_flag, char *MoiraId)
6069{
6070 char *av[3];
6071 char *call_args[7];
6072 char *pUserOu;
6073 LK_ENTRY *ptr;
6074 int rc;
6075 char member[512];
6076 char *s;
6077 char **members;
6078 int i = 0;
6079 int j = 0;
6080 int n = 0;
6081 char group_dn[512];
6082 LDAPMod *mods[20];
e8332ac3 6083 char *member_v[] = {NULL, NULL};
61a2844b 6084 char *save_argv[U_END];
e8332ac3 6085 char machine_ou[256];
6086 char NewMachineName[1024];
61a2844b 6087
6088 com_err(whoami, 0, "Populating group %s", group_name);
6089 av[0] = group_name;
6090 call_args[0] = (char *)ldap_handle;
6091 call_args[1] = dn_path;
6092 call_args[2] = group_name;
e8332ac3 6093 call_args[3] = (char *)(MOIRA_USERS | MOIRA_KERBEROS | MOIRA_STRINGS |
6094 MOIRA_MACHINE);
61a2844b 6095 call_args[4] = NULL;
6096 member_base = NULL;
6097
6098 if (rc = mr_query("get_end_members_of_list", 1, av,
6099 member_list_build, call_args))
6100 {
fe81e80b 6101 if(rc == MR_LIST)
6102 return(0);
6103
61a2844b 6104 com_err(whoami, 0, "Unable to populate list %s : %s",
6105 group_name, error_message(rc));
6106 return(3);
6107 }
6108
6109 members = (char **)malloc(sizeof(char *) * 2);
e8332ac3 6110
61a2844b 6111 if (member_base != NULL)
6112 {
6113 ptr = member_base;
6114
6115 while (ptr != NULL)
6116 {
6117 if (!strcasecmp(ptr->type, "LIST"))
6118 {
6119 ptr = ptr->next;
6120 continue;
6121 }
6122
e8332ac3 6123 if (!strcasecmp(ptr->type, "MACHINE") && !ProcessMachineContainer)
6124 {
6125 ptr = ptr->next;
6126 continue;
6127 }
6128
63d9f3c3 6129 if(!strcasecmp(ptr->type, "USER"))
61a2844b 6130 {
63d9f3c3 6131 if(!strcasecmp(ptr->member, PRODUCTION_PRINCIPAL) ||
6132 !strcasecmp(ptr->member, TEST_PRINCIPAL))
6133 {
6134 ptr = ptr->next;
6135 continue;
6136 }
6137
61a2844b 6138 if ((rc = check_user(ldap_handle, dn_path, ptr->member,
6139 "")) == AD_NO_USER_FOUND)
6140 {
6141 com_err(whoami, 0, "creating user %s", ptr->member);
6142
6143 av[0] = ptr->member;
6144 call_args[0] = (char *)ldap_handle;
6145 call_args[1] = dn_path;
6146 call_args[2] = "";
6147 call_args[3] = NULL;
6148 callback_rc = 0;
6149
6150 if (rc = mr_query("get_user_account_by_login", 1, av,
6151 save_query_info, save_argv))
6152 {
6153 com_err(whoami, 0, "Unable to create user %s "
6154 "while populating group %s.", ptr->member,
6155 group_name);
6156
6157 return(3);
6158 }
6159
6160 if (rc = user_create(U_END, save_argv, call_args))
6161 {
6162 com_err(whoami, 0, "Unable to create user %s "
6163 "while populating group %s.", ptr->member,
6164 group_name);
6165
6166 return(3);
6167 }
6168
6169 if (callback_rc)
6170 {
6171 com_err(whoami, 0, "Unable to create user %s "
6172 "while populating group %s", ptr->member,
6173 group_name);
6174
6175 return(3);
6176 }
6177 }
6178
6179 pUserOu = user_ou;
6180
6181 if(ActiveDirectory)
6182 {
6183 sprintf(member, "cn=%s,%s,%s", ptr->member, pUserOu,
6184 dn_path);
6185 }
6186 else
6187 {
6188 sprintf(member, "uid=%s,%s,%s", ptr->member, pUserOu,
6189 dn_path);
6190 }
61a2844b 6191 }
6192 else if (!strcasecmp(ptr->type, "STRING"))
6193 {
6194 if (contact_create(ldap_handle, dn_path, ptr->member,
6195 contact_ou))
6196 return(3);
6197
6198 pUserOu = contact_ou;
6199 sprintf(member, "cn=%s,%s,%s", escape_string(ptr->member),
6200 pUserOu, dn_path);
6201 }
6202 else if (!strcasecmp(ptr->type, "KERBEROS"))
6203 {
6204 if (contact_create(ldap_handle, dn_path, ptr->member,
6205 kerberos_ou))
6206 return(3);
6207
6208 pUserOu = kerberos_ou;
6209 sprintf(member, "cn=%s,%s,%s", escape_string(ptr->member),
6210 pUserOu, dn_path);
6211 }
e8332ac3 6212 else if (!strcasecmp(ptr->type, "MACHINE"))
6213 {
6214 memset(machine_ou, '\0', sizeof(machine_ou));
6215 memset(NewMachineName, '\0', sizeof(NewMachineName));
6216
6217 if (!get_machine_ou(ldap_handle, dn_path, ptr->member,
6218 machine_ou, NewMachineName))
6219 {
6220 pUserOu = machine_ou;
6221 sprintf(member, "cn=%s,%s,%s", NewMachineName, pUserOu,
6222 dn_path);
6223 }
6224 else
6225 {
6226 ptr = ptr->next;
6227 continue;
6228 }
6229 }
61a2844b 6230
6231 if(i > 1)
6232 members = (char **)realloc(members, ((i + 2) * sizeof(char *)));
6233 members[i++] = strdup(member);
6234
6235 ptr = ptr->next;
6236 }
6237
6238 linklist_free(member_base);
6239 member_base = NULL;
6240 }
6241
6242 members[i] = NULL;
e8332ac3 6243
6244 sprintf(group_dn, "cn=%s,%s,%s", group_name, group_ou, dn_path);
6245
6246 if(GroupPopulateDelete)
6247 {
6248 n = 0;
6249 ADD_ATTR("member", member_v, LDAP_MOD_REPLACE);
6250 mods[n] = NULL;
6251
6252 if ((rc = ldap_modify_s(ldap_handle, group_dn,
6253 mods)) != LDAP_SUCCESS)
6254 {
6255 com_err(whoami, 0,
6256 "Unable to populate group membership for %s: %s",
6257 group_dn, ldap_err2string(rc));
6258 }
61a2844b 6259
e8332ac3 6260 for (i = 0; i < n; i++)
6261 free(mods[i]);
6262 }
6263
61a2844b 6264 n = 0;
6265 ADD_ATTR("member", members, LDAP_MOD_REPLACE);
6266 mods[n] = NULL;
e8332ac3 6267
61a2844b 6268 if ((rc = ldap_modify_s(ldap_handle, group_dn,
6269 mods)) != LDAP_SUCCESS)
6270 {
6271 com_err(whoami, 0,
6272 "Unable to populate group membership for %s: %s",
6273 group_dn, ldap_err2string(rc));
6274 }
6275
6276 for (i = 0; i < n; i++)
6277 free(mods[i]);
e8332ac3 6278
61a2844b 6279 free(members);
6280
6281 return(0);
6282}
6283
6284int process_group(LDAP *ldap_handle, char *dn_path, char *MoiraId,
6285 char *group_name, char *group_ou, char *group_membership,
6286 int group_security_flag, int type, char *maillist)
6287{
6288 char before_desc[512];
6289 char before_name[256];
6290 char before_group_ou[256];
6291 char before_group_membership[2];
6292 char distinguishedName[256];
6293 char ad_distinguishedName[256];
6294 char filter[128];
6295 char *attr_array[3];
6296 int before_security_flag;
6297 int group_count;
6298 int rc;
6299 LK_ENTRY *group_base;
6300 LK_ENTRY *ptr;
6301 char ou_both[512];
6302 char ou_security[512];
6303 char ou_distribution[512];
6304 char ou_neither[512];
6305 char group_dn[512];
6306
6307 memset(ad_distinguishedName, '\0', sizeof(ad_distinguishedName));
6308 sprintf(distinguishedName, "CN=%s,%s,%s", group_name, group_ou, dn_path);
6309
6310 memset(filter, '\0', sizeof(filter));
6311 group_base = NULL;
6312 group_count = 0;
6313
6314 if (rc = ad_get_group(ldap_handle, dn_path, group_name,
6315 "*", MoiraId,
6316 "samAccountName", &group_base,
6317 &group_count, filter))
6318 return(rc);
6319
6320 if (type == CHECK_GROUPS)
6321 {
6322 if (group_count == 1)
6323 {
6324 strcpy(group_dn, group_base->dn);
6325
6326 if (!strcasecmp(group_dn, distinguishedName))
6327 {
6328 linklist_free(group_base);
6329 return(0);
6330 }
6331 }
6332
6333 linklist_free(group_base);
6334
6335 if (group_count == 0)
6336 return(AD_NO_GROUPS_FOUND);
6337
6338 if (group_count == 1)
6339 return(AD_WRONG_GROUP_DN_FOUND);
6340
6341 return(AD_MULTIPLE_GROUPS_FOUND);
6342 }
6343
6344 if (group_count == 0)
6345 {
6346 return(AD_NO_GROUPS_FOUND);
6347 }
6348
6349 if (group_count > 1)
6350 {
6351 ptr = group_base;
6352
6353 strcpy(group_dn, ptr->dn);
6354
6355 while (ptr != NULL)
6356 {
6357 if (!strcasecmp(group_dn, ptr->value))
6358 break;
6359
6360 ptr = ptr->next;
6361 }
6362
6363 if (ptr == NULL)
6364 {
6365 com_err(whoami, 0, "%d groups with moira id = %s", group_count,
6366 MoiraId);
6367 ptr = group_base;
6368
6369 while (ptr != NULL)
6370 {
6371 com_err(whoami, 0, "%s with moira id = %s", ptr->value, MoiraId);
6372 ptr = ptr->next;
6373 }
6374
6375 linklist_free(group_base);
6376 return(AD_MULTIPLE_GROUPS_FOUND);
6377 }
6378
6379 ptr = group_base;
6380
6381 while (ptr != NULL)
6382 {
6383 strcpy(group_dn, ptr->dn);
6384
6385 if (strcasecmp(group_dn, ptr->value))
6386 rc = ldap_delete_s(ldap_handle, ptr->value);
6387
6388 ptr = ptr->next;
6389 }
6390
6391 linklist_free(group_base);
6392 memset(filter, '\0', sizeof(filter));
6393 group_base = NULL;
6394 group_count = 0;
6395
6396 if (rc = ad_get_group(ldap_handle, dn_path, group_name,
6397 "*", MoiraId,
6398 "samAccountName", &group_base,
6399 &group_count, filter))
6400 return(rc);
6401
6402 if (group_count == 0)
6403 return(AD_NO_GROUPS_FOUND);
6404
6405 if (group_count > 1)
6406 return(AD_MULTIPLE_GROUPS_FOUND);
6407 }
6408
6409 strcpy(ad_distinguishedName, group_base->dn);
6410 linklist_free(group_base);
6411 group_base = NULL;
6412 group_count = 0;
6413
6414 attr_array[0] = "sAMAccountName";
6415 attr_array[1] = NULL;
6416
6417 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6418 &group_base, &group_count,
6419 LDAP_SCOPE_SUBTREE)) != 0)
6420 {
6421 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
6422 MoiraId, ldap_err2string(rc));
6423 return(rc);
6424 }
6425
6426 sprintf(filter, "(sAMAccountName=%s)", group_base->value);
6427
6428 if (!strcasecmp(ad_distinguishedName, distinguishedName))
6429 {
6430 linklist_free(group_base);
6431 group_base = NULL;
6432 group_count = 0;
6433 return(0);
6434 }
6435
6436 linklist_free(group_base);
6437 group_base = NULL;
6438 group_count = 0;
6439 memset(ou_both, '\0', sizeof(ou_both));
6440 memset(ou_security, '\0', sizeof(ou_security));
6441 memset(ou_distribution, '\0', sizeof(ou_distribution));
6442 memset(ou_neither, '\0', sizeof(ou_neither));
6443 memset(before_name, '\0', sizeof(before_name));
6444 memset(before_desc, '\0', sizeof(before_desc));
6445 memset(before_group_membership, '\0', sizeof(before_group_membership));
6446
6447 attr_array[0] = "name";
6448 attr_array[1] = NULL;
6449
6450 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6451 &group_base, &group_count,
6452 LDAP_SCOPE_SUBTREE)) != 0)
6453 {
6454 com_err(whoami, 0, "Unable to get list name with MoiraId = %s: %s",
6455 MoiraId, ldap_err2string(rc));
6456 return(rc);
6457 }
6458
6459 strcpy(before_name, group_base->value);
6460 linklist_free(group_base);
6461 group_base = NULL;
6462 group_count = 0;
6463
6464 attr_array[0] = "description";
6465 attr_array[1] = NULL;
6466
6467 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6468 &group_base, &group_count,
6469 LDAP_SCOPE_SUBTREE)) != 0)
6470 {
6471 com_err(whoami, 0,
6472 "Unable to get list description with MoiraId = %s: %s",
6473 MoiraId, ldap_err2string(rc));
6474 return(rc);
6475 }
6476
6477 if (group_count != 0)
6478 {
6479 strcpy(before_desc, group_base->value);
6480 linklist_free(group_base);
6481 group_base = NULL;
6482 group_count = 0;
6483 }
6484
6485 change_to_lower_case(ad_distinguishedName);
6486 strcpy(ou_both, group_ou_both);
6487 change_to_lower_case(ou_both);
6488 strcpy(ou_security, group_ou_security);
6489 change_to_lower_case(ou_security);
6490 strcpy(ou_distribution, group_ou_distribution);
6491 change_to_lower_case(ou_distribution);
6492 strcpy(ou_neither, group_ou_neither);
6493 change_to_lower_case(ou_neither);
6494
6495 if (strstr(ad_distinguishedName, ou_both))
6496 {
6497 strcpy(before_group_ou, group_ou_both);
6498 before_group_membership[0] = 'B';
6499 before_security_flag = 1;
6500 }
6501 else if (strstr(ad_distinguishedName, ou_security))
6502 {
6503 strcpy(before_group_ou, group_ou_security);
6504 before_group_membership[0] = 'S';
6505 before_security_flag = 1;
6506 }
6507 else if (strstr(ad_distinguishedName, ou_distribution))
6508 {
6509 strcpy(before_group_ou, group_ou_distribution);
6510 before_group_membership[0] = 'D';
6511 before_security_flag = 0;
6512 }
6513 else if (strstr(ad_distinguishedName, ou_neither))
6514 {
6515 strcpy(before_group_ou, group_ou_neither);
6516 before_group_membership[0] = 'N';
6517 before_security_flag = 0;
6518 }
6519 else
6520 return(AD_NO_OU_FOUND);
6521
6522 rc = group_rename(ldap_handle, dn_path, before_name,
6523 before_group_membership,
6524 before_group_ou, before_security_flag, before_desc,
6525 group_name, group_membership, group_ou,
6526 group_security_flag,
6527 before_desc, MoiraId, filter, maillist);
6528
6529 return(rc);
6530}
6531
6532void change_to_lower_case(char *ptr)
6533{
6534 int i;
6535
6536 for (i = 0; i < (int)strlen(ptr); i++)
6537 {
6538 ptr[i] = tolower(ptr[i]);
6539 }
6540}
6541
6542int ad_get_group(LDAP *ldap_handle, char *dn_path,
6543 char *group_name, char *group_membership,
6544 char *MoiraId, char *attribute,
6545 LK_ENTRY **linklist_base, int *linklist_count,
6546 char *rFilter)
6547{
6548 LK_ENTRY *pPtr;
6549 char filter[128];
6550 char *attr_array[3];
6551 char *dn;
6552 int rc;
6553
6554 (*linklist_base) = NULL;
6555 (*linklist_count) = 0;
6556
6557 if (strlen(rFilter) != 0)
6558 {
6559 strcpy(filter, rFilter);
6560 attr_array[0] = attribute;
6561 attr_array[1] = NULL;
6562
6563 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6564 linklist_base, linklist_count,
6565 LDAP_SCOPE_SUBTREE)) != 0)
6566 {
6567 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
6568 MoiraId, ldap_err2string(rc));
6569 return(rc);
6570 }
6571
6572 if ((*linklist_count) == 1)
6573 {
6574 strcpy(rFilter, filter);
6575 return(0);
6576 }
6577 }
6578
6579 linklist_free((*linklist_base));
6580 (*linklist_base) = NULL;
6581 (*linklist_count) = 0;
6582
6583 if (strlen(MoiraId) != 0)
6584 {
6585 sprintf(filter, "(&(objectClass=group)(mitMoiraId=%s))", MoiraId);
6586
6587 attr_array[0] = attribute;
6588 attr_array[1] = NULL;
6589
6590 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6591 linklist_base, linklist_count,
6592 LDAP_SCOPE_SUBTREE)) != 0)
6593 {
6594 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
6595 MoiraId, ldap_err2string(rc));
6596 return(rc);
6597 }
6598 }
6599
6600 if ((*linklist_count) > 1)
6601 {
6602 com_err(whoami, 0, "multiple groups with mitMoiraId = %s", MoiraId);
6603 pPtr = (*linklist_base);
6604
6605 while (pPtr)
6606 {
6607 com_err(whoami, 0, "groups %s has mitMoiraId = %s", pPtr->value,
6608 MoiraId);
6609 pPtr = pPtr->next;
6610 }
6611
6612 linklist_free((*linklist_base));
6613 (*linklist_base) = NULL;
6614 (*linklist_count) = 0;
6615 }
6616
6617 if ((*linklist_count) == 1)
6618 {
6619
6620 pPtr = (*linklist_base);
6621 dn = strdup(pPtr->dn);
6622 dn += 3;
6623
6624 if (!memcmp(dn, group_name, strlen(group_name)))
6625 {
6626 strcpy(rFilter, filter);
6627 return(0);
6628 }
6629 }
6630
6631 linklist_free((*linklist_base));
6632 (*linklist_base) = NULL;
6633 (*linklist_count) = 0;
6634 sprintf(filter, "(sAMAccountName=%s%s)", group_name, group_suffix);
6635
6636 attr_array[0] = attribute;
6637 attr_array[1] = NULL;
6638
6639 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6640 linklist_base, linklist_count,
6641 LDAP_SCOPE_SUBTREE)) != 0)
6642 {
6643 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
6644 MoiraId, ldap_err2string(rc));
6645 return(rc);
6646 }
6647
6648 if ((*linklist_count) == 1)
6649 {
6650 strcpy(rFilter, filter);
6651 return(0);
6652 }
6653
6654 return(0);
6655}
6656
6657int check_user(LDAP *ldap_handle, char *dn_path, char *UserName, char *MoiraId)
6658{
6659 char filter[128];
6660 char *attr_array[3];
6661 char SamAccountName[64];
6662 int group_count;
6663 int rc;
6664 LK_ENTRY *group_base;
6665 LK_ENTRY *gPtr;
6666
6667 group_count = 0;
6668 group_base = NULL;
6669
6670 if (strlen(MoiraId) != 0)
6671 {
6672 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
6673
6674 attr_array[0] = "sAMAccountName";
6675 attr_array[1] = NULL;
6676 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6677 &group_base, &group_count,
6678 LDAP_SCOPE_SUBTREE)) != 0)
6679 {
6680 com_err(whoami, 0, "Unable to process user %s : %s",
6681 UserName, ldap_err2string(rc));
6682 return(rc);
6683 }
6684
6685 if (group_count > 1)
6686 {
6687 com_err(whoami, 0, "multiple users exist with MoiraId = %s",
6688 MoiraId);
6689 gPtr = group_base;
6690
6691 while (gPtr)
6692 {
6693 com_err(whoami, 0, "user %s exist with MoiraId = %s",
6694 gPtr->value, MoiraId);
6695 gPtr = gPtr->next;
6696 }
6697 }
6698 }
6699
6700 if (group_count != 1)
6701 {
6702 linklist_free(group_base);
6703 group_count = 0;
6704 group_base = NULL;
6705 sprintf(filter, "(sAMAccountName=%s)", UserName);
6706 attr_array[0] = "sAMAccountName";
6707 attr_array[1] = NULL;
6708
6709 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6710 &group_base, &group_count,
6711 LDAP_SCOPE_SUBTREE)) != 0)
6712 {
6713 com_err(whoami, 0, "Unable to process user %s : %s",
6714 UserName, ldap_err2string(rc));
6715 return(rc);
6716 }
6717 }
6718
6719 if (group_count != 1)
6720 {
6721 linklist_free(group_base);
6722 return(AD_NO_USER_FOUND);
6723 }
6724
6725 strcpy(SamAccountName, group_base->value);
6726 linklist_free(group_base);
6727 group_count = 0;
6728 rc = 0;
6729
6730 if (strcmp(SamAccountName, UserName))
6731 {
a20c63cf 6732 com_err(whoami, 0,
6733 "User object %s with MoiraId %s has mismatched usernames "
6734 "(LDAP username %s, Moira username %s)", SamAccountName,
6735 MoiraId, SamAccountName, UserName);
61a2844b 6736 }
6737
6738 return(0);
6739}
6740
6741void container_get_dn(char *src, char *dest)
6742{
6743 char *sPtr;
6744 char *array[20];
6745 char name[256];
6746 int n;
6747
6748 memset(array, '\0', 20 * sizeof(array[0]));
6749
6750 if (strlen(src) == 0)
6751 return;
6752
6753 strcpy(name, src);
6754 sPtr = name;
6755 n = 0;
6756 array[n] = name;
6757 ++n;
6758
6759 while (*sPtr)
6760 {
6761 if ((*sPtr) == '/')
6762 {
6763 (*sPtr) = '\0';
6764 ++sPtr;
6765 array[n] = sPtr;
6766 ++n;
6767 }
6768 else
6769 ++sPtr;
6770 }
6771
6772 strcpy(dest, "OU=");
6773
6774 while (n != 0)
6775 {
6776 strcat(dest, array[n-1]);
6777 --n;
6778 if (n > 0)
6779 {
6780 strcat(dest, ",OU=");
6781 }
6782 }
6783
6784 return;
6785}
6786
6787void container_get_name(char *src, char *dest)
6788{
6789 char *sPtr;
6790 char *dPtr;
6791
6792 if (strlen(src) == 0)
6793 return;
6794
6795 sPtr = src;
6796 dPtr = src;
6797
6798 while (*sPtr)
6799 {
6800 if ((*sPtr) == '/')
6801 {
6802 dPtr = sPtr;
6803 ++dPtr;
6804 }
6805 ++sPtr;
6806 }
6807
6808 strcpy(dest, dPtr);
6809 return;
6810}
6811
6812void container_check(LDAP *ldap_handle, char *dn_path, char *name)
6813{
6814 char cName[256];
6815 char *av[7];
6816 int i;
6817 int rc;
6818
6819 strcpy(cName, name);
6820
6821 for (i = 0; i < (int)strlen(cName); i++)
6822 {
6823 if (cName[i] == '/')
6824 {
6825 cName[i] = '\0';
6826 av[CONTAINER_NAME] = cName;
6827 av[CONTAINER_DESC] = "";
6828 av[CONTAINER_LOCATION] = "";
6829 av[CONTAINER_CONTACT] = "";
6830 av[CONTAINER_TYPE] = "";
6831 av[CONTAINER_ID] = "";
6832 av[CONTAINER_ROWID] = "";
6833 rc = container_create(ldap_handle, dn_path, 7, av);
6834
6835 if (rc == LDAP_SUCCESS)
6836 {
6837 com_err(whoami, 0, "container %s created without a mitMoiraId",
6838 cName);
6839 }
6840
6841 cName[i] = '/';
6842 }
6843 }
6844}
6845
6846int container_rename(LDAP *ldap_handle, char *dn_path, int beforec,
6847 char **before, int afterc, char **after)
6848{
6849 char dName[256];
6850 char cName[256];
6851 char new_cn[128];
6852 char new_dn_path[256];
6853 char temp[256];
6854 char distinguishedName[256];
6855 char *pPtr;
6856 int rc;
6857 int i;
6858
6859 memset(cName, '\0', sizeof(cName));
6860 container_get_name(after[CONTAINER_NAME], cName);
6861
6862 if (!check_container_name(cName))
6863 {
6864 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
6865 cName);
6866 return(AD_INVALID_NAME);
6867 }
6868
6869 memset(distinguishedName, '\0', sizeof(distinguishedName));
6870
6871 if (rc = container_get_distinguishedName(ldap_handle, dn_path,
6872 distinguishedName, beforec, before))
6873 return(rc);
6874
6875 if (strlen(distinguishedName) == 0)
6876 {
6877 rc = container_create(ldap_handle, dn_path, afterc, after);
6878 return(rc);
6879 }
6880
6881 strcpy(temp, after[CONTAINER_NAME]);
6882 pPtr = temp;
6883
6884 for (i = 0; i < (int)strlen(temp); i++)
6885 {
6886 if (temp[i] == '/')
6887 {
6888 pPtr = &temp[i];
6889 }
6890 }
6891
6892 (*pPtr) = '\0';
6893
6894 container_get_dn(temp, dName);
6895
6896 if (strlen(temp) != 0)
6897 sprintf(new_dn_path, "%s,%s", dName, dn_path);
6898 else
6899 sprintf(new_dn_path, "%s", dn_path);
6900
6901 sprintf(new_cn, "OU=%s", cName);
6902
6903 container_check(ldap_handle, dn_path, after[CONTAINER_NAME]);
6904
6905 if ((rc = ldap_rename_s(ldap_handle, distinguishedName, new_cn, new_dn_path,
6906 TRUE, NULL, NULL)) != LDAP_SUCCESS)
6907 {
6908 com_err(whoami, 0, "Unable to rename container from %s to %s : %s",
6909 before[CONTAINER_NAME], after[CONTAINER_NAME],
6910 ldap_err2string(rc));
6911 return(rc);
6912 }
6913
6914 memset(dName, '\0', sizeof(dName));
6915 container_get_dn(after[CONTAINER_NAME], dName);
6916 rc = container_adupdate(ldap_handle, dn_path, dName, "", afterc, after);
6917
6918 return(rc);
6919}
6920
6921int container_delete(LDAP *ldap_handle, char *dn_path, int count, char **av)
6922{
6923 char distinguishedName[256];
6924 int rc;
6925
6926 memset(distinguishedName, '\0', sizeof(distinguishedName));
6927
6928 if (rc = container_get_distinguishedName(ldap_handle, dn_path,
6929 distinguishedName, count, av))
6930 return(rc);
6931
6932 if (strlen(distinguishedName) == 0)
6933 return(0);
6934
6935 if ((rc = ldap_delete_s(ldap_handle, distinguishedName)) != LDAP_SUCCESS)
6936 {
6937 if (rc == LDAP_NOT_ALLOWED_ON_NONLEAF)
6938 container_move_objects(ldap_handle, dn_path, distinguishedName);
6939 else
c9ef9269 6940 com_err(whoami, 0, "Unable to delete container %s from directory : %s",
61a2844b 6941 av[CONTAINER_NAME], ldap_err2string(rc));
6942 }
6943
6944 return(rc);
6945}
6946
6947int container_create(LDAP *ldap_handle, char *dn_path, int count, char **av)
6948{
6949 char *attr_array[3];
6950 LK_ENTRY *group_base;
6951 int group_count;
6952 LDAPMod *mods[20];
6953 char *objectClass_v[] = {"top",
6954 "organizationalUnit",
6955 NULL};
6956
6957 char *ou_v[] = {NULL, NULL};
6958 char *name_v[] = {NULL, NULL};
6959 char *moiraId_v[] = {NULL, NULL};
6960 char *desc_v[] = {NULL, NULL};
6961 char *managedBy_v[] = {NULL, NULL};
6962 char dName[256];
6963 char cName[256];
6964 char managedByDN[256];
6965 char filter[256];
6966 char temp[256];
6967 int n;
6968 int i;
6969 int rc;
6970
6971 memset(filter, '\0', sizeof(filter));
6972 memset(dName, '\0', sizeof(dName));
6973 memset(cName, '\0', sizeof(cName));
6974 memset(managedByDN, '\0', sizeof(managedByDN));
6975 container_get_dn(av[CONTAINER_NAME], dName);
6976 container_get_name(av[CONTAINER_NAME], cName);
6977
6978 if ((strlen(cName) == 0) || (strlen(dName) == 0))
6979 {
6980 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
6981 cName);
6982 return(AD_INVALID_NAME);
6983 }
6984
6985 if (!check_container_name(cName))
6986 {
6987 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
6988 cName);
6989 return(AD_INVALID_NAME);
6990 }
6991
6992 n = 0;
6993 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
6994 name_v[0] = cName;
6995 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
6996 ou_v[0] = cName;
6997 ADD_ATTR("ou", ou_v, LDAP_MOD_ADD);
6998
6999 if (strlen(av[CONTAINER_ROWID]) != 0)
7000 {
7001 moiraId_v[0] = av[CONTAINER_ROWID];
7002 ADD_ATTR("mitMoiraId", moiraId_v, LDAP_MOD_ADD);
7003 }
7004
7005 if (strlen(av[CONTAINER_DESC]) != 0)
7006 {
7007 desc_v[0] = av[CONTAINER_DESC];
7008 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
7009 }
7010
7011 if ((strlen(av[CONTAINER_TYPE]) != 0) && (strlen(av[CONTAINER_ID]) != 0))
7012 {
7013 if (!strcasecmp(av[CONTAINER_TYPE], "KERBEROS"))
7014 {
7015 if (!contact_create(ldap_handle, dn_path, av[CONTAINER_ID],
7016 kerberos_ou))
7017 {
7018 sprintf(managedByDN, "CN=%s,%s,%s", av[CONTAINER_ID],
7019 kerberos_ou, dn_path);
7020 managedBy_v[0] = managedByDN;
7021 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_ADD);
7022 }
7023 }
7024 else
7025 {
7026 if (!strcasecmp(av[CONTAINER_TYPE], "USER"))
7027 {
7028 sprintf(filter, "(&(cn=%s)(&(objectCategory=person)"
7029 "(objectClass=user)))", av[CONTAINER_ID]);
7030 }
7031
7032 if (!strcasecmp(av[CONTAINER_TYPE], "LIST"))
7033 {
7034 sprintf(filter, "(&(objectClass=group)(cn=%s))",
7035 av[CONTAINER_ID]);
7036 }
7037
7038 if (strlen(filter) != 0)
7039 {
7040 attr_array[0] = "distinguishedName";
7041 attr_array[1] = NULL;
7042 group_count = 0;
7043 group_base = NULL;
7044 if ((rc = linklist_build(ldap_handle, dn_path, filter,
7045 attr_array,
7046 &group_base, &group_count,
7047 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
7048 {
7049 if (group_count == 1)
7050 {
7051 strcpy(managedByDN, group_base->value);
7052 managedBy_v[0] = managedByDN;
7053 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_ADD);
7054 }
7055 linklist_free(group_base);
7056 group_base = NULL;
7057 group_count = 0;
7058 }
7059 }
7060 }
7061 }
7062
7063 mods[n] = NULL;
7064
7065 sprintf(temp, "%s,%s", dName, dn_path);
7066 rc = ldap_add_ext_s(ldap_handle, temp, mods, NULL, NULL);
7067
7068 for (i = 0; i < n; i++)
7069 free(mods[i]);
7070
7071 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
7072 {
7073 com_err(whoami, 0, "Unable to create container %s : %s",
7074 cName, ldap_err2string(rc));
7075 return(rc);
7076 }
7077
7078 if (rc == LDAP_ALREADY_EXISTS)
7079 {
7080 if (strlen(av[CONTAINER_ROWID]) != 0)
7081 rc = container_adupdate(ldap_handle, dn_path, dName, "", count, av);
7082 }
7083
7084 return(rc);
7085}
7086
7087int container_update(LDAP *ldap_handle, char *dn_path, int beforec,
7088 char **before, int afterc, char **after)
7089{
7090 char distinguishedName[256];
7091 int rc;
7092
7093 memset(distinguishedName, '\0', sizeof(distinguishedName));
7094
7095 if (rc = container_get_distinguishedName(ldap_handle, dn_path,
7096 distinguishedName, afterc, after))
7097 return(rc);
7098
7099 if (strlen(distinguishedName) == 0)
7100 {
7101 rc = container_create(ldap_handle, dn_path, afterc, after);
7102 return(rc);
7103 }
7104
7105 container_check(ldap_handle, dn_path, after[CONTAINER_NAME]);
7106 rc = container_adupdate(ldap_handle, dn_path, "", distinguishedName, afterc,
7107 after);
7108
7109 return(rc);
7110}
7111
7112int container_get_distinguishedName(LDAP *ldap_handle, char *dn_path,
7113 char *distinguishedName, int count,
7114 char **av)
7115{
7116 char *attr_array[3];
7117 LK_ENTRY *group_base;
7118 int group_count;
7119 char dName[256];
7120 char cName[256];
7121 char filter[512];
7122 int rc;
7123
7124 memset(filter, '\0', sizeof(filter));
7125 memset(dName, '\0', sizeof(dName));
7126 memset(cName, '\0', sizeof(cName));
7127 container_get_dn(av[CONTAINER_NAME], dName);
7128 container_get_name(av[CONTAINER_NAME], cName);
7129
7130 if (strlen(dName) == 0)
7131 {
7132 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
7133 av[CONTAINER_NAME]);
7134 return(AD_INVALID_NAME);
7135 }
7136
7137 if (!check_container_name(cName))
7138 {
7139 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
7140 cName);
7141 return(AD_INVALID_NAME);
7142 }
7143
7144 sprintf(filter, "(&(objectClass=organizationalUnit)(mitMoiraId=%s))",
7145 av[CONTAINER_ROWID]);
7146 attr_array[0] = "distinguishedName";
7147 attr_array[1] = NULL;
7148 group_count = 0;
7149 group_base = NULL;
7150
7151 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
7152 &group_base, &group_count,
7153 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
7154 {
7155 if (group_count == 1)
7156 {
7157 strcpy(distinguishedName, group_base->value);
7158 }
7159
7160 linklist_free(group_base);
7161 group_base = NULL;
7162 group_count = 0;
7163 }
7164
7165 if (strlen(distinguishedName) == 0)
7166 {
7167 sprintf(filter, "(&(objectClass=organizationalUnit)"
7168 "(distinguishedName=%s,%s))", dName, dn_path);
7169 attr_array[0] = "distinguishedName";
7170 attr_array[1] = NULL;
7171 group_count = 0;
7172 group_base = NULL;
7173
7174 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
7175 &group_base, &group_count,
7176 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
7177 {
7178 if (group_count == 1)
7179 {
7180 strcpy(distinguishedName, group_base->value);
7181 }
7182
7183 linklist_free(group_base);
7184 group_base = NULL;
7185 group_count = 0;
7186 }
7187 }
7188
7189 return(0);
7190}
7191
7192int container_adupdate(LDAP *ldap_handle, char *dn_path, char *dName,
7193 char *distinguishedName, int count, char **av)
7194{
7195 char *attr_array[5];
7196 LK_ENTRY *group_base;
7197 LK_ENTRY *pPtr;
7198 LDAPMod *mods[20];
7199 int group_count;
7200 char filter[512];
7201 char *moiraId_v[] = {NULL, NULL};
7202 char *desc_v[] = {NULL, NULL};
7203 char *managedBy_v[] = {NULL, NULL};
7204 char managedByDN[256];
7205 char moiraId[64];
7206 char desc[256];
7207 char ad_path[512];
7208 int rc;
7209 int i;
7210 int n;
7211
7212
7213 strcpy(ad_path, distinguishedName);
7214
7215 if (strlen(dName) != 0)
7216 sprintf(ad_path, "%s,%s", dName, dn_path);
7217
7218 sprintf(filter, "(&(objectClass=organizationalUnit)(distinguishedName=%s))",
7219 ad_path);
7220
7221 if (strlen(av[CONTAINER_ID]) != 0)
7222 sprintf(filter, "(&(objectClass=organizationalUnit)(mitMoiraId=%s))",
7223 av[CONTAINER_ROWID]);
7224
7225 attr_array[0] = "mitMoiraId";
7226 attr_array[1] = "description";
7227 attr_array[2] = "managedBy";
7228 attr_array[3] = NULL;
7229 group_count = 0;
7230 group_base = NULL;
7231
7232 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
7233 &group_base, &group_count,
7234 LDAP_SCOPE_SUBTREE)) != LDAP_SUCCESS)
7235 {
7236 com_err(whoami, 0, "Unable to retreive container info for %s : %s",
7237 av[CONTAINER_NAME], ldap_err2string(rc));
7238 return(rc);
7239 }
7240
7241 memset(managedByDN, '\0', sizeof(managedByDN));
7242 memset(moiraId, '\0', sizeof(moiraId));
7243 memset(desc, '\0', sizeof(desc));
7244 pPtr = group_base;
7245
7246 while (pPtr)
7247 {
7248 if (!strcasecmp(pPtr->attribute, "description"))
7249 strcpy(desc, pPtr->value);
7250 else if (!strcasecmp(pPtr->attribute, "managedBy"))
7251 strcpy(managedByDN, pPtr->value);
7252 else if (!strcasecmp(pPtr->attribute, "mitMoiraId"))
7253 strcpy(moiraId, pPtr->value);
7254 pPtr = pPtr->next;
7255 }
7256
7257 linklist_free(group_base);
7258 group_base = NULL;
7259 group_count = 0;
7260
7261 n = 0;
7262 if (strlen(av[CONTAINER_ROWID]) != 0)
7263 {
7264 moiraId_v[0] = av[CONTAINER_ROWID];
7265 ADD_ATTR("mitMoiraId", moiraId_v, LDAP_MOD_REPLACE);
7266 }
7267
7268 if (strlen(av[CONTAINER_DESC]) != 0)
7269 {
7270 attribute_update(ldap_handle, ad_path, av[CONTAINER_DESC], "description",
7271 dName);
7272 }
7273 else
7274 {
7275 if (strlen(desc) != 0)
7276 {
7277 attribute_update(ldap_handle, ad_path, "", "description", dName);
7278 }
7279 }
7280
7281 if ((strlen(av[CONTAINER_TYPE]) != 0) && (strlen(av[CONTAINER_ID]) != 0))
7282 {
7283 if (!strcasecmp(av[CONTAINER_TYPE], "KERBEROS"))
7284 {
7285 if (!contact_create(ldap_handle, dn_path, av[CONTAINER_ID],
7286 kerberos_ou))
7287 {
7288 sprintf(managedByDN, "CN=%s,%s,%s", av[CONTAINER_ID],
7289 kerberos_ou, dn_path);
7290 managedBy_v[0] = managedByDN;
7291 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_REPLACE);
7292 }
7293 else
7294 {
7295 if (strlen(managedByDN) != 0)
7296 {
7297 attribute_update(ldap_handle, ad_path, "", "managedBy",
7298 dName);
7299 }
7300 }
7301 }
7302 else
7303 {
7304 memset(filter, '\0', sizeof(filter));
7305
7306 if (!strcasecmp(av[CONTAINER_TYPE], "USER"))
7307 {
7308 sprintf(filter, "(&(cn=%s)(&(objectCategory=person)"
7309 "(objectClass=user)))", av[CONTAINER_ID]);
7310 }
7311
7312 if (!strcasecmp(av[CONTAINER_TYPE], "LIST"))
7313 {
7314 sprintf(filter, "(&(objectClass=group)(cn=%s))",
7315 av[CONTAINER_ID]);
7316 }
7317
7318 if (strlen(filter) != 0)
7319 {
7320 attr_array[0] = "distinguishedName";
7321 attr_array[1] = NULL;
7322 group_count = 0;
7323 group_base = NULL;
7324 if ((rc = linklist_build(ldap_handle, dn_path, filter,
7325 attr_array, &group_base, &group_count,
7326 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
7327 {
7328 if (group_count == 1)
7329 {
7330 strcpy(managedByDN, group_base->value);
7331 managedBy_v[0] = managedByDN;
7332 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_REPLACE);
7333 }
7334 else
7335 {
7336 if (strlen(managedByDN) != 0)
7337 {
7338 attribute_update(ldap_handle, ad_path, "",
7339 "managedBy", dName);
7340 }
7341 }
7342
7343 linklist_free(group_base);
7344 group_base = NULL;
7345 group_count = 0;
7346 }
7347 }
7348 else
7349 {
7350 if (strlen(managedByDN) != 0)
7351 {
7352 attribute_update(ldap_handle, ad_path, "", "managedBy",
7353 dName);
7354 }
7355 }
7356 }
7357 }
7358
7359 mods[n] = NULL;
7360
7361 if (n == 0)
7362 return(LDAP_SUCCESS);
7363
7364 rc = ldap_modify_s(ldap_handle, ad_path, mods);
7365
7366 for (i = 0; i < n; i++)
7367 free(mods[i]);
7368
7369 if (rc != LDAP_SUCCESS)
7370 {
7371 com_err(whoami, 0, "Unable to modify container info for %s : %s",
7372 av[CONTAINER_NAME], ldap_err2string(rc));
7373 return(rc);
7374 }
7375
7376 return(rc);
7377}
7378
7379int container_move_objects(LDAP *ldap_handle, char *dn_path, char *dName)
7380{
7381 char *attr_array[3];
7382 LK_ENTRY *group_base;
7383 LK_ENTRY *pPtr;
7384 int group_count;
7385 char filter[512];
7386 char new_cn[128];
7387 char temp[256];
7388 int rc;
7389 int NumberOfEntries = 10;
7390 int i;
7391 int count;
7392
7393 rc = ldap_set_option(ldap_handle, LDAP_OPT_SIZELIMIT, &NumberOfEntries);
7394
7395 for (i = 0; i < 3; i++)
7396 {
7397 memset(filter, '\0', sizeof(filter));
7398
7399 if (i == 0)
7400 {
7401 strcpy(filter, "(!(|(objectClass=computer)"
7402 "(objectClass=organizationalUnit)))");
7403 attr_array[0] = "cn";
7404 attr_array[1] = NULL;
7405 }
7406 else if (i == 1)
7407 {
7408 strcpy(filter, "(objectClass=computer)");
7409 attr_array[0] = "cn";
7410 attr_array[1] = NULL;
7411 }
7412 else
7413 {
7414 strcpy(filter, "(objectClass=organizationalUnit)");
7415 attr_array[0] = "ou";
7416 attr_array[1] = NULL;
7417 }
7418
7419 while (1)
7420 {
7421 if ((rc = linklist_build(ldap_handle, dName, filter, attr_array,
7422 &group_base, &group_count,
7423 LDAP_SCOPE_SUBTREE)) != LDAP_SUCCESS)
7424 {
7425 break;
7426 }
7427
7428 if (group_count == 0)
7429 break;
7430
7431 pPtr = group_base;
7432
7433 while(pPtr)
7434 {
7435 if (!strcasecmp(pPtr->attribute, "cn"))
7436 {
7437 sprintf(new_cn, "cn=%s", pPtr->value);
7438 if (i == 0)
7439 sprintf(temp, "%s,%s", orphans_other_ou, dn_path);
7440 if (i == 1)
7441 sprintf(temp, "%s,%s", orphans_machines_ou, dn_path);
7442 count = 1;
7443
7444 while (1)
7445 {
7446 rc = ldap_rename_s(ldap_handle, pPtr->dn, new_cn, temp,
7447 TRUE, NULL, NULL);
7448 if (rc == LDAP_ALREADY_EXISTS)
7449 {
7450 sprintf(new_cn, "cn=%s_%d", pPtr->value, count);
7451 ++count;
7452 }
7453 else
7454 break;
7455 }
7456 }
7457 else if (!strcasecmp(pPtr->attribute, "ou"))
7458 {
7459 rc = ldap_delete_s(ldap_handle, pPtr->dn);
7460 }
7461
7462 pPtr = pPtr->next;
7463 }
7464
7465 linklist_free(group_base);
7466 group_base = NULL;
7467 group_count = 0;
7468 }
7469 }
7470
7471 return(0);
7472}
7473
7474int get_machine_ou(LDAP *ldap_handle, char *dn_path, char *member,
7475 char *machine_ou, char *NewMachineName)
7476{
7477 LK_ENTRY *group_base;
7478 int group_count;
7479 int i;
7480 char filter[128];
7481 char *attr_array[3];
7482 char cn[256];
7483 char dn[256];
7484 char temp[256];
7485 char *pPtr;
7486 int rc;
7487
7488 strcpy(NewMachineName, member);
7489 rc = moira_connect();
7490 rc = GetMachineName(NewMachineName);
7491 moira_disconnect();
7492
7493 if (strlen(NewMachineName) == 0)
7494 {
7495 com_err(whoami, 0, "Unable to find alais for machine %s in Moira",
7496 member);
7497 return(1);
7498 }
7499
7500 pPtr = NULL;
7501 pPtr = strchr(NewMachineName, '.');
7502
7503 if (pPtr != NULL)
7504 (*pPtr) = '\0';
7505
7506 group_base = NULL;
7507 group_count = 0;
7508 sprintf(filter, "(sAMAccountName=%s$)", NewMachineName);
7509 attr_array[0] = "cn";
7510 attr_array[1] = NULL;
7511 sprintf(temp, "%s", dn_path);
7512
7513 if ((rc = linklist_build(ldap_handle, temp, filter, attr_array,
7514 &group_base, &group_count,
7515 LDAP_SCOPE_SUBTREE)) != 0)
7516 {
7517 com_err(whoami, 0, "Unable to process machine %s : %s",
7518 member, ldap_err2string(rc));
7519 return(1);
7520 }
7521
7522 if (group_count != 1)
7523 {
61a2844b 7524 return(1);
7525 }
7526
7527 strcpy(dn, group_base->dn);
7528 strcpy(cn, group_base->value);
7529
7530 for (i = 0; i < (int)strlen(dn); i++)
7531 dn[i] = tolower(dn[i]);
7532
7533 for (i = 0; i < (int)strlen(cn); i++)
7534 cn[i] = tolower(cn[i]);
7535
7536 linklist_free(group_base);
7537 pPtr = NULL;
7538 pPtr = strstr(dn, cn);
7539
7540 if (pPtr == NULL)
7541 {
7542 com_err(whoami, 0, "Unable to process machine %s",
7543 member);
7544 return(1);
7545 }
7546
7547 pPtr += strlen(cn) + 1;
7548 strcpy(machine_ou, pPtr);
7549 pPtr = NULL;
7550 pPtr = strstr(machine_ou, "dc=");
7551
7552 if (pPtr == NULL)
7553 {
7554 com_err(whoami, 0, "Unable to process machine %s",
7555 member);
7556 return(1);
7557 }
7558
7559 --pPtr;
7560 (*pPtr) = '\0';
7561
7562 return(0);
7563}
7564
7565int machine_move_to_ou(LDAP *ldap_handle, char * dn_path,
7566 char *MoiraMachineName, char *DestinationOu)
7567{
7568 char NewCn[128];
7569 char OldDn[512];
7570 char MachineName[128];
7571 char filter[128];
7572 char *attr_array[3];
7573 char NewOu[256];
7574 char *cPtr = NULL;
7575 int group_count;
7576 long rc;
7577 LK_ENTRY *group_base;
7578
7579 group_count = 0;
7580 group_base = NULL;
7581
7582 strcpy(MachineName, MoiraMachineName);
7583 rc = GetMachineName(MachineName);
7584
7585 if (strlen(MachineName) == 0)
7586 {
7587 com_err(whoami, 0, "Unable to find alais for machine %s in Moira",
7588 MoiraMachineName);
7589 return(1);
7590 }
7591
7592 cPtr = strchr(MachineName, '.');
7593
7594 if (cPtr != NULL)
7595 (*cPtr) = '\0';
7596
7597 sprintf(filter, "(sAMAccountName=%s$)", MachineName);
7598 attr_array[0] = "sAMAccountName";
7599 attr_array[1] = NULL;
7600
7601 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
7602 &group_base,
7603 &group_count, LDAP_SCOPE_SUBTREE)) != 0)
7604 {
7605 com_err(whoami, 0, "Unable to process machine %s : %s",
7606 MoiraMachineName, ldap_err2string(rc));
7607 return(1);
7608 }
7609
7610 if (group_count == 1)
7611 strcpy(OldDn, group_base->dn);
7612
7613 linklist_free(group_base);
7614 group_base = NULL;
7615
7616 if (group_count != 1)
7617 {
c9ef9269 7618 com_err(whoami, 0, "Unable to find machine %s in directory: %s",
61a2844b 7619 MoiraMachineName);
7620 return(1);
7621 }
7622
7623 sprintf(NewOu, "%s,%s", DestinationOu, dn_path);
7624 cPtr = strchr(OldDn, ',');
7625
7626 if (cPtr != NULL)
7627 {
7628 ++cPtr;
7629 if (!strcasecmp(cPtr, NewOu))
7630 return(0);
7631 }
7632
7633 sprintf(NewCn, "CN=%s", MachineName);
7634 rc = ldap_rename_s(ldap_handle, OldDn, NewCn, NewOu, TRUE, NULL, NULL);
7635
7636 return(rc);
7637}
7638
7639int machine_check(LDAP *ldap_handle, char *dn_path, char *machine_name)
7640{
7641 char Name[128];
7642 char *pPtr;
7643 int rc;
7644
7645 memset(Name, '\0', sizeof(Name));
7646 strcpy(Name, machine_name);
7647 pPtr = NULL;
7648 pPtr = strchr(Name, '.');
7649
7650 if (pPtr != NULL)
7651 (*pPtr) = '\0';
7652
7653 strcat(Name, "$");
7654 return(!(rc = checkADname(ldap_handle, dn_path, Name)));
7655}
7656
7657int machine_get_moira_container(LDAP *ldap_handle, char *dn_path,
7658 char *machine_name, char *container_name)
7659{
7660 int rc;
7661 char *av[2];
7662 char *call_args[2];
7663
7664 av[0] = machine_name;
7665 call_args[0] = (char *)container_name;
7666 rc = mr_query("get_machine_to_container_map", 1, av,
7667 machine_GetMoiraContainer, call_args);
7668 return(rc);
7669}
7670
7671int machine_GetMoiraContainer(int ac, char **av, void *ptr)
7672{
7673 char **call_args;
7674
7675 call_args = ptr;
7676 strcpy(call_args[0], av[1]);
7677 return(0);
7678}
7679
7680int Moira_container_group_create(char **after)
7681{
7682 long rc;
7683 char GroupName[64];
7684 char *argv[20];
7685
7686 memset(GroupName, '\0', sizeof(GroupName));
7687 rc = Moira_groupname_create(GroupName, after[CONTAINER_NAME],
7688 after[CONTAINER_ROWID]);
7689 if (rc)
7690 return rc;
7691
7692 argv[L_NAME] = GroupName;
7693 argv[L_ACTIVE] = "1";
7694 argv[L_PUBLIC] = "0";
7695 argv[L_HIDDEN] = "0";
7696 argv[L_MAILLIST] = "0";
7697 argv[L_GROUP] = "1";
7698 argv[L_GID] = UNIQUE_GID;
7699 argv[L_NFSGROUP] = "0";
7700 argv[L_MAILMAN] = "0";
7701 argv[L_MAILMAN_SERVER] = "[NONE]";
7702 argv[L_DESC] = "auto created container group";
7703 argv[L_ACE_TYPE] = "USER";
7704 argv[L_MEMACE_TYPE] = "USER";
7705 argv[L_ACE_NAME] = "sms";
7706 argv[L_MEMACE_NAME] = "sms";
7707
7708 if (rc = mr_query("add_list", 15, argv, NULL, NULL))
7709 {
7710 com_err(whoami, 0,
7711 "Unable to create container group %s for container %s: %s",
7712 GroupName, after[CONTAINER_NAME], error_message(rc));
7713 }
7714
7715 Moira_setContainerGroup(after[CONTAINER_NAME], GroupName);
7716 Moira_addGroupToParent(after[CONTAINER_NAME], GroupName);
7717
7718 return(rc);
7719}
7720
7721int Moira_container_group_update(char **before, char **after)
7722{
7723 long rc;
7724 char BeforeGroupName[64];
7725 char AfterGroupName[64];
7726 char *argv[20];
7727
7728 if (!strcasecmp(after[CONTAINER_NAME], before[CONTAINER_NAME]))
7729 return(0);
7730
7731 memset(BeforeGroupName, '\0', sizeof(BeforeGroupName));
7732 Moira_getGroupName(after[CONTAINER_NAME], BeforeGroupName, 0);
7733 if (strlen(BeforeGroupName) == 0)
7734 return(0);
7735
7736 memset(AfterGroupName, '\0', sizeof(AfterGroupName));
7737 rc = Moira_groupname_create(AfterGroupName, after[CONTAINER_NAME],
7738 after[CONTAINER_ROWID]);
7739 if (rc)
7740 return rc;
7741
7742 if (strcasecmp(BeforeGroupName, AfterGroupName))
7743 {
7744 argv[L_NAME] = BeforeGroupName;
7745 argv[L_NAME + 1] = AfterGroupName;
7746 argv[L_ACTIVE + 1] = "1";
7747 argv[L_PUBLIC + 1] = "0";
7748 argv[L_HIDDEN + 1] = "0";
7749 argv[L_MAILLIST + 1] = "0";
7750 argv[L_GROUP + 1] = "1";
7751 argv[L_GID + 1] = UNIQUE_GID;
7752 argv[L_NFSGROUP + 1] = "0";
7753 argv[L_MAILMAN + 1] = "0";
7754 argv[L_MAILMAN_SERVER + 1] = "[NONE]";
7755 argv[L_DESC + 1] = "auto created container group";
7756 argv[L_ACE_TYPE + 1] = "USER";
7757 argv[L_MEMACE_TYPE + 1] = "USER";
7758 argv[L_ACE_NAME + 1] = "sms";
7759 argv[L_MEMACE_NAME + 1] = "sms";
7760
7761 if (rc = mr_query("update_list", 16, argv, NULL, NULL))
7762 {
7763 com_err(whoami, 0,
7764 "Unable to rename container group from %s to %s: %s",
7765 BeforeGroupName, AfterGroupName, error_message(rc));
7766 }
7767 }
7768
7769 return(rc);
7770}
7771
7772int Moira_container_group_delete(char **before)
7773{
7774 long rc = 0;
7775 char *argv[13];
7776 char GroupName[64];
7777 char ParentGroupName[64];
7778
7779 memset(ParentGroupName, '\0', sizeof(ParentGroupName));
7780 Moira_getGroupName(before[CONTAINER_NAME], ParentGroupName, 1);
7781
7782 memset(GroupName, '\0', sizeof(GroupName));
7783
7784 if (strcmp(before[CONTAINER_GROUP_NAME], "[none]"))
7785 strcpy(GroupName, before[CONTAINER_GROUP_NAME]);
7786
7787 if ((strlen(ParentGroupName) != 0) && (strlen(GroupName) != 0))
7788 {
7789 argv[0] = ParentGroupName;
7790 argv[1] = "LIST";
7791 argv[2] = GroupName;
7792
7793 if (rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL))
7794 {
7795 com_err(whoami, 0,
7796 "Unable to delete container group %s from list: %s",
7797 GroupName, ParentGroupName, error_message(rc));
7798 }
7799 }
7800
7801 if (strlen(GroupName) != 0)
7802 {
7803 argv[0] = GroupName;
7804
7805 if (rc = mr_query("delete_list", 1, argv, NULL, NULL))
7806 {
7807 com_err(whoami, 0, "Unable to delete container group %s : %s",
7808 GroupName, error_message(rc));
7809 }
7810 }
7811
7812 return(rc);
7813}
7814
7815int Moira_groupname_create(char *GroupName, char *ContainerName,
7816 char *ContainerRowID)
7817{
7818 char *ptr;
7819 char *ptr1;
7820 char temp[64];
7821 char newGroupName[64];
7822 char tempGroupName[64];
7823 char tempgname[64];
7824 char *argv[1];
7825 int i;
7826 long rc;
7827
7828 strcpy(temp, ContainerName);
7829
7830 ptr1 = strrchr(temp, '/');
7831
7832 if (ptr1 != NULL)
7833 {
7834 *ptr1 = '\0';
7835 ptr = ++ptr1;
7836 ptr1 = strrchr(temp, '/');
7837
7838 if (ptr1 != NULL)
7839 {
7840 sprintf(tempgname, "%s-%s", ++ptr1, ptr);
7841 }
7842 else
7843 strcpy(tempgname, ptr);
7844 }
7845 else
7846 strcpy(tempgname, temp);
7847
7848 if (strlen(tempgname) > 25)
7849 tempgname[25] ='\0';
7850
7851 sprintf(newGroupName, "cnt-%s", tempgname);
7852
7853 /* change everything to lower case */
7854 ptr = newGroupName;
7855
7856 while (*ptr)
7857 {
7858 if (isupper(*ptr))
7859 *ptr = tolower(*ptr);
7860
7861 if (*ptr == ' ')
7862 *ptr = '-';
7863
7864 ptr++;
7865 }
7866
7867 strcpy(tempGroupName, newGroupName);
7868 i = (int)'0';
7869
7870 /* append 0-9 then a-z if a duplicate is found */
7871 while(1)
7872 {
7873 argv[0] = newGroupName;
7874
7875 if (rc = mr_query("get_list_info", 1, argv, NULL, NULL))
7876 {
7877 if (rc == MR_NO_MATCH)
7878 break;
7879 com_err(whoami, 0, "Moira error while creating group name for "
7880 "container %s : %s", ContainerName, error_message(rc));
7881 return rc;
7882 }
7883
7884 sprintf(newGroupName, "%s-%c", tempGroupName, i);
7885
7886 if (i == (int)'z')
7887 {
7888 com_err(whoami, 0, "Unable to find a unique group name for "
7889 "container %s: too many duplicate container names",
7890 ContainerName);
7891 return 1;
7892 }
7893
7894 if (i == '9')
7895 i = 'a';
7896 else
7897 i++;
7898 }
7899
7900 strcpy(GroupName, newGroupName);
7901 return(0);
7902}
7903
7904int Moira_setContainerGroup(char *origContainerName, char *GroupName)
7905{
7906 long rc;
7907 char *argv[3];
7908
7909 argv[0] = origContainerName;
7910 argv[1] = GroupName;
7911
7912 if ((rc = mr_query("set_container_list", 2, argv, NULL, NULL)))
7913 {
7914 com_err(whoami, 0,
7915 "Unable to set container group %s in container %s: %s",
7916 GroupName, origContainerName, error_message(rc));
7917 }
7918
7919 return(0);
7920}
7921
7922int Moira_addGroupToParent(char *origContainerName, char *GroupName)
7923 {
7924 char ContainerName[64];
7925 char ParentGroupName[64];
7926 char *argv[3];
7927 long rc;
7928
7929 strcpy(ContainerName, origContainerName);
7930
7931 Moira_getGroupName(ContainerName, ParentGroupName, 1);
7932
7933 /* top-level container */
7934 if (strlen(ParentGroupName) == 0)
7935 return(0);
7936
7937 argv[0] = ParentGroupName;
7938 argv[1] = "LIST";
7939 argv[2] = GroupName;
7940
7941 if ((rc = mr_query("add_member_to_list", 3, argv, NULL, NULL)))
7942 {
7943 com_err(whoami, 0,
7944 "Unable to add container group %s to parent group %s: %s",
7945 GroupName, ParentGroupName, error_message(rc));
7946 }
7947
7948 return(0);
7949 }
7950
7951int Moira_getContainerGroup(int ac, char **av, void *ptr)
7952{
7953 char **call_args;
7954
7955 call_args = ptr;
7956 strcpy(call_args[0], av[1]);
7957
7958 return(0);
7959}
7960
7961int Moira_getGroupName(char *origContainerName, char *GroupName,
7962 int ParentFlag)
7963{
7964 char ContainerName[64];
7965 char *argv[3];
7966 char *call_args[3];
7967 char *ptr;
7968 long rc;
7969
7970 strcpy(ContainerName, origContainerName);
7971
7972 if (ParentFlag)
7973 {
7974 ptr = strrchr(ContainerName, '/');
7975
7976 if (ptr != NULL)
7977 (*ptr) = '\0';
7978 else
7979 return(0);
7980 }
7981
7982 argv[0] = ContainerName;
7983 argv[1] = NULL;
7984 call_args[0] = GroupName;
7985 call_args[1] = NULL;
7986
7987 if (!(rc = mr_query("get_container_list", 1, argv, Moira_getContainerGroup,
7988 call_args)))
7989 {
7990 if (strlen(GroupName) != 0)
7991 return(0);
7992 }
7993
7994 if (rc)
7995 com_err(whoami, 0, "Unable to get container group from container %s: %s",
7996 ContainerName, error_message(rc));
7997 else
7998 com_err(whoami, 0, "Unable to get container group from container %s",
7999 ContainerName);
8000
8001 return(0);
8002}
8003
8004int Moira_process_machine_container_group(char *MachineName, char* GroupName,
8005 int DeleteMachine)
8006{
8007 char *argv[3];
8008 long rc;
8009
8010 if (strcmp(GroupName, "[none]") == 0)
8011 return 0;
8012
8013 argv[0] = GroupName;
8014 argv[1] = "MACHINE";
8015 argv[2] = MachineName;
8016
8017 if (!DeleteMachine)
8018 rc = mr_query("add_member_to_list", 3, argv, NULL, NULL);
8019 else
8020 rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL);
8021
8022 if (rc)
8023 {
8024 com_err(whoami, 0, "Unable to add machine %s to container group%s: %s",
8025 MachineName, GroupName, error_message(rc));
8026 }
8027
8028 return(0);
8029}
8030
8031int GetMachineName(char *MachineName)
8032{
8033 char *args[2];
8034 char NewMachineName[1024];
8035 char *szDot;
8036 int rc = 0;
8037 int i;
8038 DWORD dwLen = 0;
8039 char *call_args[2];
8040
8041 // If the address happens to be in the top-level MIT domain, great!
8042 strcpy(NewMachineName, MachineName);
8043
8044 for (i = 0; i < (int)strlen(NewMachineName); i++)
8045 NewMachineName[i] = toupper(NewMachineName[i]);
8046
8047 szDot = strchr(NewMachineName,'.');
8048
8049 if ((szDot) && (!strcasecmp(szDot+1, DOMAIN_SUFFIX)))
8050 {
8051 return(0);
8052 }
8053
8054 // If not, see if it has a Moira alias in the top-level MIT domain.
8055 memset(NewMachineName, '\0', sizeof(NewMachineName));
8056 args[0] = "*";
8057 args[1] = MachineName;
8058 call_args[0] = NewMachineName;
8059 call_args[1] = NULL;
8060
8061 if (rc = mr_query("get_hostalias", 2, args, ProcessMachineName, call_args))
8062 {
8063 com_err(whoami, 0, "Unable to resolve machine name %s : %s",
8064 MachineName, error_message(rc));
8065 strcpy(MachineName, "");
8066 return(0);
8067 }
8068
8069 if (strlen(NewMachineName) != 0)
8070 strcpy(MachineName, NewMachineName);
8071 else
8072 strcpy(MachineName, "");
8073
8074 return(0);
8075}
8076
8077int ProcessMachineName(int ac, char **av, void *ptr)
8078{
8079 char **call_args;
8080 char MachineName[1024];
8081 char *szDot;
8082 int i;
8083
8084 call_args = ptr;
8085
8086 if (strlen(call_args[0]) == 0)
8087 {
8088 strcpy(MachineName, av[0]);
8089
8090 for (i = 0; i < (int)strlen(MachineName); i++)
8091 MachineName[i] = toupper(MachineName[i]);
8092
8093 szDot = strchr(MachineName,'.');
8094
8095 if ((szDot) && (!strcasecmp(szDot+1,DOMAIN_SUFFIX)))
8096 {
8097 strcpy(call_args[0], MachineName);
8098 }
8099 }
8100
8101 return(0);
8102}
8103
8104void SwitchSFU(LDAPMod **mods, int *UseSFU30, int n)
8105{
8106 int i;
8107
8108 if (*UseSFU30)
8109 {
8110 for (i = 0; i < n; i++)
8111 {
8112 if (!strcmp(mods[i]->mod_type, "msSFU30UidNumber"))
8113 mods[i]->mod_type = "uidNumber";
8114 }
8115
8116 (*UseSFU30) = 0;
8117 }
8118 else
8119 {
8120 for (i = 0; i < n; i++)
8121 {
8122 if (!strcmp(mods[i]->mod_type, "uidNumber"))
8123 mods[i]->mod_type = "msSFU30UidNumber";
8124 }
8125
8126 (*UseSFU30) = 1;
8127 }
8128}
8129
8130int SetHomeDirectory(LDAP *ldap_handle, char *user_name,
8131 char *DistinguishedName,
8132 char *WinHomeDir, char *WinProfileDir,
8133 char **homedir_v, char **winProfile_v,
8134 char **drives_v, LDAPMod **mods,
8135 int OpType, int n)
8136{
61a2844b 8137 char cWeight[3];
8138 char cPath[1024];
8139 char path[1024];
8140 char winPath[1024];
8141 char winProfile[1024];
8142 char homeDrive[8];
8143 char homedir[1024];
8144 char apple_homedir[1024];
8145 char *apple_homedir_v[] = {NULL, NULL};
8146 int last_weight;
8147 int i;
8148 int rc;
8149 LDAPMod *DelMods[20];
5f6343e6 8150 char *argv[3];
8151 char *save_argv[FS_END];
8152 char *fsgroup_save_argv[2];
8153
61a2844b 8154 memset(homeDrive, '\0', sizeof(homeDrive));
8155 memset(path, '\0', sizeof(path));
8156 memset(winPath, '\0', sizeof(winPath));
8157 memset(winProfile, '\0', sizeof(winProfile));
61a2844b 8158
8159 if(!ActiveDirectory)
8160 {
5f6343e6 8161 if (rc = moira_connect())
8162 {
c9ef9269 8163 critical_alert("Ldap incremental",
5f6343e6 8164 "Error contacting Moira server : %s",
8165 error_message(rc));
8166 return;
8167 }
8168
8169 argv[0] = user_name;
8170
8171 if (!(rc = mr_query("get_filesys_by_label", 1, argv, save_query_info,
8172 save_argv)))
8173 {
8174 if(!strcmp(save_argv[FS_TYPE], "FSGROUP") ||
8175 !strcmp(save_argv[FS_TYPE], "MUL"))
61a2844b 8176 {
5f6343e6 8177
8178 argv[0] = save_argv[FS_NAME];
8179 fsgCount = 0;
8180
8181 if (!(rc = mr_query("get_fsgroup_members", 1, argv,
8182 save_fsgroup_info, fsgroup_save_argv)))
61a2844b 8183 {
5f6343e6 8184 if(fsgCount)
8185 {
8186 argv[0] = fsgroup_save_argv[0];
8187
8188 if (!(rc = mr_query("get_filesys_by_label", 1, argv,
8189 save_query_info, save_argv)))
8190 {
8191 strcpy(path, save_argv[FS_PACK]);
8192 }
8193 }
61a2844b 8194 }
8195 }
5f6343e6 8196 else
8197 {
8198 strcpy(path, save_argv[FS_PACK]);
8199 }
61a2844b 8200 }
5f6343e6 8201
8202 moira_disconnect();
8203
8204 if (strlen(path))
61a2844b 8205 {
5f6343e6 8206 if (!strnicmp(path, AFS, strlen(AFS)))
61a2844b 8207 {
5f6343e6 8208 sprintf(homedir, "%s", path);
8209 sprintf(apple_homedir, "%s/MacData", path);
8210 homedir_v[0] = homedir;
8211 apple_homedir_v[0] = apple_homedir;
61a2844b 8212 ADD_ATTR("homeDirectory", homedir_v, OpType);
8213 ADD_ATTR("apple-user-homeDirectory", apple_homedir_v,
8214 OpType);
8215 }
8216 }
5f6343e6 8217 else
8218 {
8219 homedir_v[0] = "NONE";
8220 apple_homedir_v[0] = "NONE";
8221 ADD_ATTR("homeDirectory", homedir_v, OpType);
8222 ADD_ATTR("apple-user-homeDirectory", apple_homedir_v,
8223 OpType);
8224 }
8225
61a2844b 8226 return(n);
8227 }
5f6343e6 8228
61a2844b 8229 if ((!strcasecmp(WinHomeDir, "[afs]")) ||
8230 (!strcasecmp(WinProfileDir, "[afs]")))
8231 {
5f6343e6 8232 if (rc = moira_connect())
8233 {
c9ef9269 8234 critical_alert("Ldap incremental",
5f6343e6 8235 "Error contacting Moira server : %s",
8236 error_message(rc));
8237 return;
8238 }
8239
8240 argv[0] = user_name;
61a2844b 8241
5f6343e6 8242 if (!(rc = mr_query("get_filesys_by_label", 1, argv, save_query_info,
8243 save_argv)))
8244 {
8245 if(!strcmp(save_argv[FS_TYPE], "FSGROUP") ||
8246 !strcmp(save_argv[FS_TYPE], "MUL"))
8247 {
8248
8249 argv[0] = save_argv[FS_NAME];
8250 fsgCount = 0;
8251
8252 if (!(rc = mr_query("get_fsgroup_members", 1, argv,
8253 save_fsgroup_info, fsgroup_save_argv)))
8254 {
8255 if(fsgCount)
8256 {
8257 argv[0] = fsgroup_save_argv[0];
8258
8259 if (!(rc = mr_query("get_filesys_by_label", 1, argv,
8260 save_query_info, save_argv)))
8261 {
8262 strcpy(path, save_argv[FS_PACK]);
8263 }
8264 }
8265 }
8266 }
8267 else
8268 {
8269 strcpy(path, save_argv[FS_PACK]);
8270 }
8271 }
8272
8273 moira_disconnect();
61a2844b 8274
5f6343e6 8275 if (strlen(path))
8276 {
8277 if (!strnicmp(path, AFS, strlen(AFS)))
8278 {
8279 AfsToWinAfs(path, winPath);
8280 strcpy(winProfile, winPath);
8281 strcat(winProfile, "\\.winprofile");
8282 }
8283 }
61a2844b 8284 else
8285 return(n);
8286 }
8287
8288 if ((!strcasecmp(WinHomeDir, "[dfs]")) ||
8289 (!strcasecmp(WinProfileDir, "[dfs]")))
8290 {
8291 sprintf(path, "\\\\%s\\dfs\\profiles\\%c\\%s", ldap_domain,
8292 user_name[0], user_name);
8293
8294 if (!strcasecmp(WinProfileDir, "[dfs]"))
8295 {
8296 strcpy(winProfile, path);
8297 strcat(winProfile, "\\.winprofile");
8298 }
8299
8300 if (!strcasecmp(WinHomeDir, "[dfs]"))
8301 strcpy(winPath, path);
8302 }
8303
61a2844b 8304 if (!strcasecmp(WinHomeDir, "[local]"))
8305 memset(winPath, '\0', sizeof(winPath));
8306 else if (!strcasecmp(WinHomeDir, "[afs]") ||
8307 !strcasecmp(WinHomeDir, "[dfs]"))
8308 {
8309 strcpy(homeDrive, "H:");
8310 }
8311 else
8312 {
8313 strcpy(winPath, WinHomeDir);
8314 if (!strncmp(WinHomeDir, "\\\\", 2))
8315 {
8316 strcpy(homeDrive, "H:");
8317 }
8318 }
8319
8320 // nothing needs to be done if WinProfileDir is [afs].
8321 if (!strcasecmp(WinProfileDir, "[local]"))
8322 memset(winProfile, '\0', sizeof(winProfile));
8323 else if (strcasecmp(WinProfileDir, "[afs]") &&
8324 strcasecmp(WinProfileDir, "[dfs]"))
8325 {
8326 strcpy(winProfile, WinProfileDir);
8327 }
8328
8329 if (strlen(winProfile) != 0)
8330 {
8331 if (winProfile[strlen(winProfile) - 1] == '\\')
8332 winProfile[strlen(winProfile) - 1] = '\0';
8333 }
8334
8335 if (strlen(winPath) != 0)
8336 {
8337 if (winPath[strlen(winPath) - 1] == '\\')
8338 winPath[strlen(winPath) - 1] = '\0';
8339 }
8340
8341 if ((winProfile[1] == ':') && (strlen(winProfile) == 2))
8342 strcat(winProfile, "\\");
8343
8344 if ((winPath[1] == ':') && (strlen(winPath) == 2))
8345 strcat(winPath, "\\");
8346
8347 if (strlen(winPath) == 0)
8348 {
8349 if (OpType == LDAP_MOD_REPLACE)
8350 {
8351 i = 0;
8352 DEL_ATTR("homeDirectory", LDAP_MOD_DELETE);
8353 DelMods[i] = NULL;
8354 //unset homeDirectory attribute for user.
8355 rc = ldap_modify_s(ldap_handle, DistinguishedName, DelMods);
8356 free(DelMods[0]);
8357 }
8358 }
8359 else
8360 {
8361 homedir_v[0] = strdup(winPath);
8362 ADD_ATTR("homeDirectory", homedir_v, OpType);
8363 }
8364
8365 if (strlen(winProfile) == 0)
8366 {
8367 if (OpType == LDAP_MOD_REPLACE)
8368 {
8369 i = 0;
8370 DEL_ATTR("profilePath", LDAP_MOD_DELETE);
8371 DelMods[i] = NULL;
8372 //unset profilePate attribute for user.
8373 rc = ldap_modify_s(ldap_handle, DistinguishedName, DelMods);
8374 free(DelMods[0]);
8375 }
8376 }
8377 else
8378 {
8379 winProfile_v[0] = strdup(winProfile);
8380 ADD_ATTR("profilePath", winProfile_v, OpType);
8381 }
8382
8383 if (strlen(homeDrive) == 0)
8384 {
8385 if (OpType == LDAP_MOD_REPLACE)
8386 {
8387 i = 0;
8388 DEL_ATTR("homeDrive", LDAP_MOD_DELETE);
8389 DelMods[i] = NULL;
8390 //unset homeDrive attribute for user
8391 rc = ldap_modify_s(ldap_handle, DistinguishedName, DelMods);
8392 free(DelMods[0]);
8393 }
8394 }
8395 else
8396 {
8397 drives_v[0] = strdup(homeDrive);
8398 ADD_ATTR("homeDrive", drives_v, OpType);
8399 }
8400
8401 return(n);
8402}
8403
8404int attribute_update(LDAP *ldap_handle, char *distinguished_name,
8405 char *attribute_value, char *attribute, char *user_name)
8406{
8407 char *mod_v[] = {NULL, NULL};
8408 LDAPMod *DelMods[20];
8409 LDAPMod *mods[20];
8410 int n;
8411 int i;
8412 int rc;
8413
8414 if (strlen(attribute_value) == 0)
8415 {
8416 i = 0;
8417 DEL_ATTR(attribute, LDAP_MOD_DELETE);
8418 DelMods[i] = NULL;
8419 rc = ldap_modify_s(ldap_handle, distinguished_name, DelMods);
8420 free(DelMods[0]);
8421 }
8422 else
8423 {
8424 n = 0;
8425 mod_v[0] = attribute_value;
8426 ADD_ATTR(attribute, mod_v, LDAP_MOD_REPLACE);
8427 mods[n] = NULL;
8428
8429 if ((rc = ldap_modify_s(ldap_handle, distinguished_name,
8430 mods)) != LDAP_SUCCESS)
8431 {
8432 free(mods[0]);
8433 n = 0;
8434 mod_v[0] = attribute_value;
8435 ADD_ATTR(attribute, mod_v, LDAP_MOD_ADD);
8436 mods[n] = NULL;
8437
8438 if ((rc = ldap_modify_s(ldap_handle, distinguished_name,
8439 mods)) != LDAP_SUCCESS)
8440 {
8441 com_err(whoami, 0, "Unable to change the %s attribute for %s "
c9ef9269 8442 "in the directory : %s",
61a2844b 8443 attribute, user_name, ldap_err2string(rc));
8444 }
8445 }
8446
8447 free(mods[0]);
8448 }
8449
8450 return(rc);
8451}
8452
8453void StringTrim(char *StringToTrim)
8454{
8455 char *t, *s;
8456 char *save;
8457
8458 save = strdup(StringToTrim);
8459
8460 s = save;
8461
8462 while (isspace(*s))
8463 s++;
8464
8465 /* skip to end of string */
8466 if (*s == '\0')
8467 {
8468 if (*save)
8469 *save = '\0';
8470 strcpy(StringToTrim, save);
8471 return;
8472 }
8473
8474 for (t = s; *t; t++)
8475 continue;
8476
8477 while (t > s)
8478 {
8479 --t;
8480 if (!isspace(*t))
8481 {
8482 t++;
8483 break;
8484 }
8485 }
8486
8487 if (*t)
8488 *t = '\0';
8489
8490 strcpy(StringToTrim, s);
8491 return;
8492}
8493
8494int ReadConfigFile(char *DomainName)
8495{
8496 int Count;
8497 int i;
8498 int k;
8499 char temp[256];
8500 char temp1[256];
8501 FILE *fptr;
8502
8503 Count = 0;
8504
8505 sprintf(temp, "%s%s.cfg", CFG_PATH, DomainName);
8506
8507 if ((fptr = fopen(temp, "r")) != NULL)
8508 {
8509 while (fgets(temp, sizeof(temp), fptr) != 0)
8510 {
8511 for (i = 0; i < (int)strlen(temp); i++)
8512 temp[i] = toupper(temp[i]);
8513
8514 if (temp[strlen(temp) - 1] == '\n')
8515 temp[strlen(temp) - 1] = '\0';
8516
8517 StringTrim(temp);
8518
8519 if (strlen(temp) == 0)
8520 continue;
8521
8522 if (!strncmp(temp, DOMAIN, strlen(DOMAIN)))
8523 {
8524 if (strlen(temp) > (strlen(DOMAIN)))
8525 {
8526 strcpy(ldap_domain, &temp[strlen(DOMAIN)]);
8527 StringTrim(ldap_domain);
8528 }
8529 }
8530 else if (!strncmp(temp, REALM, strlen(REALM)))
8531 {
8532 if (strlen(temp) > (strlen(REALM)))
8533 {
8534 strcpy(ldap_realm, &temp[strlen(REALM)]);
8535 StringTrim(ldap_realm);
8536 }
8537 }
8538 else if (!strncmp(temp, PORT, strlen(PORT)))
8539 {
8540 if (strlen(temp) > (strlen(PORT)))
8541 {
8542 strcpy(ldap_port, &temp[strlen(PORT)]);
8543 StringTrim(ldap_port);
8544 }
8545 }
8546 else if (!strncmp(temp, PRINCIPALNAME, strlen(PRINCIPALNAME)))
8547 {
8548 if (strlen(temp) > (strlen(PRINCIPALNAME)))
8549 {
8550 strcpy(PrincipalName, &temp[strlen(PRINCIPALNAME)]);
8551 StringTrim(PrincipalName);
8552 }
8553 }
8554 else if (!strncmp(temp, SERVER, strlen(SERVER)))
8555 {
8556 if (strlen(temp) > (strlen(SERVER)))
8557 {
8558 ServerList[Count] = calloc(1, 256);
8559 strcpy(ServerList[Count], &temp[strlen(SERVER)]);
8560 StringTrim(ServerList[Count]);
8561 ++Count;
8562 }
8563 }
8564 else if (!strncmp(temp, MSSFU, strlen(MSSFU)))
8565 {
8566 if (strlen(temp) > (strlen(MSSFU)))
8567 {
8568 strcpy(temp1, &temp[strlen(MSSFU)]);
8569 StringTrim(temp1);
8570 if (!strcmp(temp1, SFUTYPE))
8571 UseSFU30 = 1;
8572 }
8573 }
8574 else if (!strncmp(temp, GROUP_SUFFIX, strlen(GROUP_SUFFIX)))
8575 {
8576 if (strlen(temp) > (strlen(GROUP_SUFFIX)))
8577 {
8578 strcpy(temp1, &temp[strlen(GROUP_SUFFIX)]);
8579 StringTrim(temp1);
8580 if (!strcasecmp(temp1, "NO"))
8581 {
8582 UseGroupSuffix = 0;
8583 memset(group_suffix, '\0', sizeof(group_suffix));
8584 }
8585 }
8586 }
8587 else if (!strncmp(temp, GROUP_TYPE, strlen(GROUP_TYPE)))
8588 {
8589 if (strlen(temp) > (strlen(GROUP_TYPE)))
8590 {
8591 strcpy(temp1, &temp[strlen(GROUP_TYPE)]);
8592 StringTrim(temp1);
8593 if (!strcasecmp(temp1, "UNIVERSAL"))
8594 UseGroupUniversal = 1;
8595 }
8596 }
8597 else if (!strncmp(temp, SET_GROUP_ACE, strlen(SET_GROUP_ACE)))
8598 {
8599 if (strlen(temp) > (strlen(SET_GROUP_ACE)))
8600 {
8601 strcpy(temp1, &temp[strlen(SET_GROUP_ACE)]);
8602 StringTrim(temp1);
8603 if (!strcasecmp(temp1, "NO"))
8604 SetGroupAce = 0;
8605 }
8606 }
8607 else if (!strncmp(temp, SET_PASSWORD, strlen(SET_PASSWORD)))
8608 {
8609 if (strlen(temp) > (strlen(SET_PASSWORD)))
8610 {
8611 strcpy(temp1, &temp[strlen(SET_PASSWORD)]);
8612 StringTrim(temp1);
8613 if (!strcasecmp(temp1, "NO"))
8614 SetPassword = 0;
8615 }
8616 }
8617 else if (!strncmp(temp, EXCHANGE, strlen(EXCHANGE)))
8618 {
8619 if (strlen(temp) > (strlen(EXCHANGE)))
8620 {
8621 strcpy(temp1, &temp[strlen(EXCHANGE)]);
8622 StringTrim(temp1);
8623 if (!strcasecmp(temp1, "YES"))
8624 Exchange = 1;
8625 }
8626 }
8627 else if (!strncmp(temp, PROCESS_MACHINE_CONTAINER,
8628 strlen(PROCESS_MACHINE_CONTAINER)))
8629 {
8630 if (strlen(temp) > (strlen(PROCESS_MACHINE_CONTAINER)))
8631 {
8632 strcpy(temp1, &temp[strlen(PROCESS_MACHINE_CONTAINER)]);
8633 StringTrim(temp1);
8634 if (!strcasecmp(temp1, "NO"))
8635 ProcessMachineContainer = 0;
8636 }
8637 }
8638 else if (!strncmp(temp, ACTIVE_DIRECTORY,
8639 strlen(ACTIVE_DIRECTORY)))
8640 {
8641 if (strlen(temp) > (strlen(ACTIVE_DIRECTORY)))
8642 {
8643 strcpy(temp1, &temp[strlen(ACTIVE_DIRECTORY)]);
8644 StringTrim(temp1);
8645 if (!strcasecmp(temp1, "NO"))
8646 ActiveDirectory = 0;
8647 }
8648 }
e8332ac3 8649 else if (!strncmp(temp, GROUP_POPULATE_MEMBERS,
8650 strlen(GROUP_POPULATE_MEMBERS)))
8651 {
8652 if (strlen(temp) > (strlen(GROUP_POPULATE_MEMBERS)))
8653 {
8654 strcpy(temp1, &temp[strlen(GROUP_POPULATE_MEMBERS)]);
8655 StringTrim(temp1);
8656 if (!strcasecmp(temp1, "DELETE"))
8657 {
8658 GroupPopulateDelete = 1;
8659 }
8660 }
8661 }
61a2844b 8662 else
8663 {
8664 if (strlen(ldap_domain) != 0)
8665 {
8666 memset(ldap_domain, '\0', sizeof(ldap_domain));
8667 break;
8668 }
8669
8670 if (strlen(temp) != 0)
8671 strcpy(ldap_domain, temp);
8672 }
8673 }
8674 fclose(fptr);
8675 }
8676
8677 if (strlen(ldap_domain) == 0)
8678 {
8679 strcpy(ldap_domain, DomainName);
8680 }
8681
8682 if (Count == 0)
8683 return(0);
8684
8685 for (i = 0; i < Count; i++)
8686 {
8687 if (ServerList[i] != 0)
8688 {
8689 for (k = 0; k < (int)strlen(ServerList[i]); k++)
8690 ServerList[i][k] = toupper(ServerList[i][k]);
8691 }
8692 }
8693
8694 return(0);
8695}
8696
8697int ReadDomainList()
8698{
8699 int Count;
8700 int i;
8701 char temp[128];
8702 char temp1[128];
8703 FILE *fptr;
8704 unsigned char c[11];
8705 unsigned char stuff[256];
8706 int rc;
8707 int ok;
8708
8709 Count = 0;
8710 sprintf(temp, "%s%s", CFG_PATH, WINADCFG);
8711
8712 if ((fptr = fopen(temp, "r")) != NULL)
8713 {
8714 while (fgets(temp, sizeof(temp), fptr) != 0)
8715 {
8716 for (i = 0; i < (int)strlen(temp); i++)
8717 temp[i] = toupper(temp[i]);
8718
8719 if (temp[strlen(temp) - 1] == '\n')
8720 temp[strlen(temp) - 1] = '\0';
8721
8722 StringTrim(temp);
8723
8724 if (strlen(temp) == 0)
8725 continue;
8726
8727 if (!strncmp(temp, DOMAIN, strlen(DOMAIN)))
8728 {
8729 if (strlen(temp) > (strlen(DOMAIN)))
8730 {
8731 strcpy(temp1, &temp[strlen(DOMAIN)]);
8732 StringTrim(temp1);
8733 strcpy(temp, temp1);
8734 }
8735 }
8736
8737 strcpy(DomainNames[Count], temp);
8738 StringTrim(DomainNames[Count]);
8739 ++Count;
8740 }
8741
8742 fclose(fptr);
8743 }
8744
8745 if (Count == 0)
8746 {
8747 critical_alert("incremental", "%s", "ldap.incr cannot run due to a "
8748 "configuration error in ldap.cfg");
8749 return(1);
8750 }
8751
8752 return(0);
8753}
8754
8755int email_isvalid(const char *address) {
8756 int count = 0;
8757 const char *c, *domain;
8758 static char *rfc822_specials = "()<>@,;:\\\"[]";
8759
8760 if(address[strlen(address) - 1] == '.')
8761 return 0;
8762
8763 /* first we validate the name portion (name@domain) */
8764 for (c = address; *c; c++) {
8765 if (*c == '\"' && (c == address || *(c - 1) == '.' || *(c - 1) ==
8766 '\"')) {
8767 while (*++c) {
8768 if (*c == '\"')
8769 break;
8770 if (*c == '\\' && (*++c == ' '))
8771 continue;
8772 if (*c <= ' ' || *c >= 127)
8773 return 0;
8774 }
8775
8776 if (!*c++)
8777 return 0;
8778 if (*c == '@')
8779 break;
8780 if (*c != '.')
8781 return 0;
8782 continue;
8783 }
8784
8785 if (*c == '@')
8786 break;
8787 if (*c <= ' ' || *c >= 127)
8788 return 0;
8789 if (strchr(rfc822_specials, *c))
8790 return 0;
8791 }
8792
8793 if (c == address || *(c - 1) == '.')
8794 return 0;
8795
8796 /* next we validate the domain portion (name@domain) */
8797 if (!*(domain = ++c)) return 0;
8798 do {
8799 if (*c == '.') {
8800 if (c == domain || *(c - 1) == '.')
8801 return 0;
8802 count++;
8803 }
8804 if (*c <= ' ' || *c >= 127)
8805 return 0;
8806 if (strchr(rfc822_specials, *c))
8807 return 0;
8808 } while (*++c);
8809
8810 return (count >= 1);
8811}
8812
8813int find_homeMDB(LDAP *ldap_handle, char *dn_path, char **homeMDB,
8814 char **homeServerName)
8815{
8816 LK_ENTRY *group_base;
8817 LK_ENTRY *sub_group_base;
8818 LK_ENTRY *gPtr;
8819 LK_ENTRY *sub_gPtr;
8820 int group_count;
8821 int sub_group_count;
8822 char filter[1024];
8823 char sub_filter[1024];
8824 char search_path[1024];
8825 char range[1024];
8826 char *attr_array[3];
8827 char *s;
8828 int homeMDB_count = -1;
8829 int rc;
8830 int i;
8831 int mdbbl_count;
8832 int rangeStep = 1500;
8833 int rangeLow = 0;
8834 int rangeHigh = rangeLow + (rangeStep - 1);
8835 int isLast = 0;
8836
8837 /* Grumble..... microsoft not making it searchable from the root *grr* */
8838
8839 memset(filter, '\0', sizeof(filter));
8840 memset(search_path, '\0', sizeof(search_path));
8841
8842 sprintf(filter, "(objectClass=msExchMDB)");
8843 sprintf(search_path, "CN=Configuration,%s", dn_path);
8844 attr_array[0] = "distinguishedName";
8845 attr_array[1] = NULL;
8846
8847 group_base = NULL;
8848 group_count = 0;
8849
8850 if ((rc = linklist_build(ldap_handle, search_path, filter, attr_array,
8851 &group_base, &group_count,
8852 LDAP_SCOPE_SUBTREE)) != 0)
8853 {
8854 com_err(whoami, 0, "Unable to find msExchMDB %s",
8855 ldap_err2string(rc));
8856 return(rc);
8857 }
8858
8859 if (group_count)
8860 {
8861 gPtr = group_base;
8862
8863 while(gPtr) {
8864 if (((s = strstr(gPtr->dn, "Public")) != (char *) NULL) ||
8865 ((s = strstr(gPtr->dn, "Recover")) != (char *) NULL) ||
8866 ((s = strstr(gPtr->dn, "Reserve")) != (char *) NULL))
8867 {
8868 gPtr = gPtr->next;
8869 continue;
8870 }
8871
8872 /*
8873 * Due to limits in active directory we need to use the LDAP
8874 * range semantics to query and return all the values in
8875 * large lists, we will stop increasing the range when
8876 * the result count is 0.
8877 */
8878
8879 i = 0;
8880 mdbbl_count = 0;
8881
8882 for(;;)
8883 {
8884 memset(sub_filter, '\0', sizeof(sub_filter));
8885 memset(range, '\0', sizeof(range));
8886 sprintf(sub_filter, "(objectClass=msExchMDB)");
8887
8888 if(isLast)
8889 sprintf(range, "homeMDBBL;Range=%d-*", rangeLow);
8890 else
8891 sprintf(range, "homeMDBBL;Range=%d-%d", rangeLow, rangeHigh);
8892
8893 attr_array[0] = range;
8894 attr_array[1] = NULL;
8895
8896 sub_group_base = NULL;
8897 sub_group_count = 0;
8898
8899 if ((rc = linklist_build(ldap_handle, gPtr->dn, sub_filter,
8900 attr_array, &sub_group_base,
8901 &sub_group_count,
8902 LDAP_SCOPE_SUBTREE)) != 0)
8903 {
8904 com_err(whoami, 0, "Unable to find homeMDBBL %s",
8905 ldap_err2string(rc));
8906 return(rc);
8907 }
8908
8909 if(!sub_group_count)
8910 {
8911 if(isLast)
8912 {
8913 isLast = 0;
8914 rangeLow = 0;
8915 rangeHigh = rangeLow + (rangeStep - 1);
8916 break;
8917 }
8918 else
8919 isLast++;
8920 }
8921
8922 mdbbl_count += sub_group_count;
8923 rangeLow = rangeHigh + 1;
8924 rangeHigh = rangeLow + (rangeStep - 1);
8925 }
8926
8927 /* First time through, need to initialize or update the least used */
8928
8929 com_err(whoami, 0, "Mail store %s, count %d", gPtr->dn,
8930 mdbbl_count);
8931
8932 if(mdbbl_count < homeMDB_count || homeMDB_count == -1)
8933 {
8934 homeMDB_count = mdbbl_count;
8935 *homeMDB = strdup(gPtr->dn);
8936 }
8937
8938 gPtr = gPtr->next;
8939 linklist_free(sub_group_base);
8940 }
8941 }
8942
8943 linklist_free(group_base);
8944
8945 /*
8946 * Ok found the server least allocated need to now query to get its
8947 * msExchHomeServerName so we can set it as a user attribute
8948 */
8949
8950 attr_array[0] = "legacyExchangeDN";
8951 attr_array[1] = NULL;
8952
8953 group_count = 0;
8954 group_base = NULL;
8955
8956 if ((rc = linklist_build(ldap_handle, *homeMDB, filter,
8957 attr_array, &group_base,
8958 &group_count,
8959 LDAP_SCOPE_SUBTREE)) != 0)
8960 {
8961 com_err(whoami, 0, "Unable to find msExchHomeServerName %s",
8962 ldap_err2string(rc));
8963 return(rc);
8964 }
8965
8966 if(group_count)
8967 {
8968 *homeServerName = strdup(group_base->value);
8969 if((s = strrchr(*homeServerName, '/')) != (char *) NULL)
8970 {
8971 *s = '\0';
8972 }
8973 }
8974
8975 linklist_free(group_base);
8976
8977 return(rc);
8978}
8979
8980char *lowercase(char *s)
8981{
8982 char *p;
8983
8984 for (p = s; *p; p++)
8985 {
8986 if (isupper(*p))
8987 *p = tolower(*p);
8988 }
8989 return s;
8990}
8991
8992char *uppercase(char *s)
8993{
8994 char *p;
8995
8996 for (p = s; *p; p++)
8997 {
8998 if (islower(*p))
8999 *p = toupper(*p);
9000 }
9001 return s;
9002}
9003
9004char *escape_string(char *s)
9005{
9006 char *p, *q;
9007 char string[1024];
9008 char temp[1024];
9009 int i = 0;
9010 int spaces = 0;
9011
9012 memset(string, '\0', sizeof(string));
9013
9014 q = s;
9015
61a2844b 9016 /* Escape any special characters */
9017
9018 for(; *q != '\0'; q++) {
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 if(*q == ';')
9032 string[i++] = '\\';
9033 if(*q == '#')
9034 string[i++] = '\\';
9035 if(*q == '=')
9036 string[i++] = '\\';
9037
9038 string[i++] = *q;
9039 }
9040
9041 return strdup(string);
9042}
9043
9044int save_query_info(int argc, char **argv, void *hint)
9045{
9046 int i;
9047 char **nargv = hint;
9048
9049 for(i = 0; i < argc; i++)
9050 nargv[i] = strdup(argv[i]);
9051
9052 return MR_CONT;
9053}
5f6343e6 9054
9055int save_fsgroup_info(int argc, char **argv, void *hint)
9056{
9057 int i;
9058 char **nargv = hint;
9059
9060 if(!fsgCount)
9061 {
9062 for(i = 0; i < argc; i++)
9063 nargv[i] = strdup(argv[i]);
9064
9065 fsgCount++;
9066 }
9067
9068 return MR_CONT;
9069}
This page took 1.267386 seconds and 5 git commands to generate.