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