]> andersk Git - moira.git/blame_incremental - incremental/winad/winad.c
Replace filter with search_filter.
[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("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("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("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("AD incremental",
1101 "Error contacting 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("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("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("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("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("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("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("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 com_err(whoami, 0, "AD_GET_GROUP: samname is %s%s", group_name, group_suffix);
5740 attr_array[0] = attribute;
5741 attr_array[1] = NULL;
5742
5743 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5744 linklist_base, linklist_count,
5745 LDAP_SCOPE_SUBTREE)) != 0)
5746 {
5747 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
5748 MoiraId, ldap_err2string(rc));
5749 return(rc);
5750 }
5751
5752 if ((*linklist_count) == 1)
5753 {
5754 strcpy(rFilter, filter);
5755 return(0);
5756 }
5757
5758 return(0);
5759}
5760
5761int check_user(LDAP *ldap_handle, char *dn_path, char *UserName, char *MoiraId)
5762{
5763 char filter[128];
5764 char *attr_array[3];
5765 char SamAccountName[64];
5766 int group_count;
5767 int rc;
5768 LK_ENTRY *group_base;
5769 LK_ENTRY *gPtr;
5770
5771 group_count = 0;
5772 group_base = NULL;
5773
5774 if (strlen(MoiraId) != 0)
5775 {
5776 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
5777 attr_array[0] = "sAMAccountName";
5778 attr_array[1] = NULL;
5779 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5780 &group_base, &group_count,
5781 LDAP_SCOPE_SUBTREE)) != 0)
5782 {
5783 com_err(whoami, 0, "Unable to process user %s : %s",
5784 UserName, ldap_err2string(rc));
5785 return(rc);
5786 }
5787
5788 if (group_count > 1)
5789 {
5790 com_err(whoami, 0, "multiple users exist with MoiraId = %s",
5791 MoiraId);
5792 gPtr = group_base;
5793
5794 while (gPtr)
5795 {
5796 com_err(whoami, 0, "user %s exist with MoiraId = %s",
5797 gPtr->value, MoiraId);
5798 gPtr = gPtr->next;
5799 }
5800 }
5801 }
5802
5803 if (group_count != 1)
5804 {
5805 linklist_free(group_base);
5806 group_count = 0;
5807 group_base = NULL;
5808 sprintf(filter, "(sAMAccountName=%s)", UserName);
5809 attr_array[0] = "sAMAccountName";
5810 attr_array[1] = NULL;
5811
5812 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5813 &group_base, &group_count,
5814 LDAP_SCOPE_SUBTREE)) != 0)
5815 {
5816 com_err(whoami, 0, "Unable to process user %s : %s",
5817 UserName, ldap_err2string(rc));
5818 return(rc);
5819 }
5820 }
5821
5822 if (group_count != 1)
5823 {
5824 linklist_free(group_base);
5825 return(AD_NO_USER_FOUND);
5826 }
5827
5828 strcpy(SamAccountName, group_base->value);
5829 linklist_free(group_base);
5830 group_count = 0;
5831 rc = 0;
5832
5833 if (strcmp(SamAccountName, UserName))
5834 {
5835 rc = user_rename(ldap_handle, dn_path, SamAccountName,
5836 UserName);
5837 }
5838
5839 return(0);
5840}
5841
5842void container_get_dn(char *src, char *dest)
5843{
5844 char *sPtr;
5845 char *array[20];
5846 char name[256];
5847 int n;
5848
5849 memset(array, '\0', 20 * sizeof(array[0]));
5850
5851 if (strlen(src) == 0)
5852 return;
5853
5854 strcpy(name, src);
5855 sPtr = name;
5856 n = 0;
5857 array[n] = name;
5858 ++n;
5859
5860 while (*sPtr)
5861 {
5862 if ((*sPtr) == '/')
5863 {
5864 (*sPtr) = '\0';
5865 ++sPtr;
5866 array[n] = sPtr;
5867 ++n;
5868 }
5869 else
5870 ++sPtr;
5871 }
5872
5873 strcpy(dest, "OU=");
5874
5875 while (n != 0)
5876 {
5877 strcat(dest, array[n-1]);
5878 --n;
5879 if (n > 0)
5880 {
5881 strcat(dest, ",OU=");
5882 }
5883 }
5884
5885 return;
5886}
5887
5888void container_get_name(char *src, char *dest)
5889{
5890 char *sPtr;
5891 char *dPtr;
5892
5893 if (strlen(src) == 0)
5894 return;
5895
5896 sPtr = src;
5897 dPtr = src;
5898
5899 while (*sPtr)
5900 {
5901 if ((*sPtr) == '/')
5902 {
5903 dPtr = sPtr;
5904 ++dPtr;
5905 }
5906 ++sPtr;
5907 }
5908
5909 strcpy(dest, dPtr);
5910 return;
5911}
5912
5913void container_check(LDAP *ldap_handle, char *dn_path, char *name)
5914{
5915 char cName[256];
5916 char *av[7];
5917 int i;
5918 int rc;
5919
5920 strcpy(cName, name);
5921
5922 for (i = 0; i < (int)strlen(cName); i++)
5923 {
5924 if (cName[i] == '/')
5925 {
5926 cName[i] = '\0';
5927 av[CONTAINER_NAME] = cName;
5928 av[CONTAINER_DESC] = "";
5929 av[CONTAINER_LOCATION] = "";
5930 av[CONTAINER_CONTACT] = "";
5931 av[CONTAINER_TYPE] = "";
5932 av[CONTAINER_ID] = "";
5933 av[CONTAINER_ROWID] = "";
5934 rc = container_create(ldap_handle, dn_path, 7, av);
5935
5936 if (rc == LDAP_SUCCESS)
5937 {
5938 com_err(whoami, 0, "container %s created without a mitMoiraId",
5939 cName);
5940 }
5941
5942 cName[i] = '/';
5943 }
5944 }
5945}
5946
5947int container_rename(LDAP *ldap_handle, char *dn_path, int beforec,
5948 char **before, int afterc, char **after)
5949{
5950 char dName[256];
5951 char cName[256];
5952 char new_cn[128];
5953 char new_dn_path[256];
5954 char temp[256];
5955 char distinguishedName[256];
5956 char *pPtr;
5957 int rc;
5958 int i;
5959
5960 memset(cName, '\0', sizeof(cName));
5961 container_get_name(after[CONTAINER_NAME], cName);
5962
5963 if (!check_container_name(cName))
5964 {
5965 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
5966 cName);
5967 return(AD_INVALID_NAME);
5968 }
5969
5970 memset(distinguishedName, '\0', sizeof(distinguishedName));
5971
5972 if (rc = container_get_distinguishedName(ldap_handle, dn_path,
5973 distinguishedName, beforec, before))
5974 return(rc);
5975
5976 if (strlen(distinguishedName) == 0)
5977 {
5978 rc = container_create(ldap_handle, dn_path, afterc, after);
5979 return(rc);
5980 }
5981
5982 strcpy(temp, after[CONTAINER_NAME]);
5983 pPtr = temp;
5984
5985 for (i = 0; i < (int)strlen(temp); i++)
5986 {
5987 if (temp[i] == '/')
5988 {
5989 pPtr = &temp[i];
5990 }
5991 }
5992
5993 (*pPtr) = '\0';
5994
5995 container_get_dn(temp, dName);
5996
5997 if (strlen(temp) != 0)
5998 sprintf(new_dn_path, "%s,%s", dName, dn_path);
5999 else
6000 sprintf(new_dn_path, "%s", dn_path);
6001
6002 sprintf(new_cn, "OU=%s", cName);
6003
6004 container_check(ldap_handle, dn_path, after[CONTAINER_NAME]);
6005
6006 if ((rc = ldap_rename_s(ldap_handle, distinguishedName, new_cn, new_dn_path,
6007 TRUE, NULL, NULL)) != LDAP_SUCCESS)
6008 {
6009 com_err(whoami, 0, "Unable to rename container from %s to %s : %s",
6010 before[CONTAINER_NAME], after[CONTAINER_NAME],
6011 ldap_err2string(rc));
6012 return(rc);
6013 }
6014
6015 memset(dName, '\0', sizeof(dName));
6016 container_get_dn(after[CONTAINER_NAME], dName);
6017 rc = container_adupdate(ldap_handle, dn_path, dName, "", afterc, after);
6018
6019 return(rc);
6020}
6021
6022int container_delete(LDAP *ldap_handle, char *dn_path, int count, char **av)
6023{
6024 char distinguishedName[256];
6025 int rc;
6026
6027 memset(distinguishedName, '\0', sizeof(distinguishedName));
6028
6029 if (rc = container_get_distinguishedName(ldap_handle, dn_path,
6030 distinguishedName, count, av))
6031 return(rc);
6032
6033 if (strlen(distinguishedName) == 0)
6034 return(0);
6035
6036 if ((rc = ldap_delete_s(ldap_handle, distinguishedName)) != LDAP_SUCCESS)
6037 {
6038 if (rc == LDAP_NOT_ALLOWED_ON_NONLEAF)
6039 container_move_objects(ldap_handle, dn_path, distinguishedName);
6040 else
6041 com_err(whoami, 0, "Unable to delete container %s from AD : %s",
6042 av[CONTAINER_NAME], ldap_err2string(rc));
6043 }
6044
6045 return(rc);
6046}
6047
6048int container_create(LDAP *ldap_handle, char *dn_path, int count, char **av)
6049{
6050 char *attr_array[3];
6051 LK_ENTRY *group_base;
6052 int group_count;
6053 LDAPMod *mods[20];
6054 char *objectClass_v[] = {"top",
6055 "organizationalUnit",
6056 NULL};
6057
6058 char *ou_v[] = {NULL, NULL};
6059 char *name_v[] = {NULL, NULL};
6060 char *moiraId_v[] = {NULL, NULL};
6061 char *desc_v[] = {NULL, NULL};
6062 char *managedBy_v[] = {NULL, NULL};
6063 char dName[256];
6064 char cName[256];
6065 char managedByDN[256];
6066 char filter[256];
6067 char temp[256];
6068 int n;
6069 int i;
6070 int rc;
6071
6072 memset(filter, '\0', sizeof(filter));
6073 memset(dName, '\0', sizeof(dName));
6074 memset(cName, '\0', sizeof(cName));
6075 memset(managedByDN, '\0', sizeof(managedByDN));
6076 container_get_dn(av[CONTAINER_NAME], dName);
6077 container_get_name(av[CONTAINER_NAME], cName);
6078
6079 if ((strlen(cName) == 0) || (strlen(dName) == 0))
6080 {
6081 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
6082 cName);
6083 return(AD_INVALID_NAME);
6084 }
6085
6086 if (!check_container_name(cName))
6087 {
6088 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
6089 cName);
6090 return(AD_INVALID_NAME);
6091 }
6092
6093 n = 0;
6094 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
6095 name_v[0] = cName;
6096 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
6097 ou_v[0] = cName;
6098 ADD_ATTR("ou", ou_v, LDAP_MOD_ADD);
6099
6100 if (strlen(av[CONTAINER_ROWID]) != 0)
6101 {
6102 moiraId_v[0] = av[CONTAINER_ROWID];
6103 ADD_ATTR("mitMoiraId", moiraId_v, LDAP_MOD_ADD);
6104 }
6105
6106 if (strlen(av[CONTAINER_DESC]) != 0)
6107 {
6108 desc_v[0] = av[CONTAINER_DESC];
6109 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
6110 }
6111
6112 if ((strlen(av[CONTAINER_TYPE]) != 0) && (strlen(av[CONTAINER_ID]) != 0))
6113 {
6114 if (!strcasecmp(av[CONTAINER_TYPE], "KERBEROS"))
6115 {
6116 if (!contact_create(ldap_handle, dn_path, av[CONTAINER_ID],
6117 kerberos_ou))
6118 {
6119 sprintf(managedByDN, "CN=%s,%s,%s", av[CONTAINER_ID],
6120 kerberos_ou, dn_path);
6121 managedBy_v[0] = managedByDN;
6122 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_ADD);
6123 }
6124 }
6125 else
6126 {
6127 if (!strcasecmp(av[CONTAINER_TYPE], "USER"))
6128 {
6129 sprintf(filter, "(&(cn=%s)(&(objectCategory=person)"
6130 "(objectClass=user)))", av[CONTAINER_ID]);
6131 }
6132
6133 if (!strcasecmp(av[CONTAINER_TYPE], "LIST"))
6134 {
6135 sprintf(filter, "(&(objectClass=group)(cn=%s))",
6136 av[CONTAINER_ID]);
6137 }
6138
6139 if (strlen(filter) != 0)
6140 {
6141 attr_array[0] = "distinguishedName";
6142 attr_array[1] = NULL;
6143 group_count = 0;
6144 group_base = NULL;
6145 if ((rc = linklist_build(ldap_handle, dn_path, filter,
6146 attr_array,
6147 &group_base, &group_count,
6148 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
6149 {
6150 if (group_count == 1)
6151 {
6152 strcpy(managedByDN, group_base->value);
6153 managedBy_v[0] = managedByDN;
6154 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_ADD);
6155 }
6156 linklist_free(group_base);
6157 group_base = NULL;
6158 group_count = 0;
6159 }
6160 }
6161 }
6162 }
6163
6164 mods[n] = NULL;
6165
6166 sprintf(temp, "%s,%s", dName, dn_path);
6167 rc = ldap_add_ext_s(ldap_handle, temp, mods, NULL, NULL);
6168
6169 for (i = 0; i < n; i++)
6170 free(mods[i]);
6171
6172 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
6173 {
6174 com_err(whoami, 0, "Unable to create container %s : %s",
6175 cName, ldap_err2string(rc));
6176 return(rc);
6177 }
6178
6179 if (rc == LDAP_ALREADY_EXISTS)
6180 {
6181 if (strlen(av[CONTAINER_ROWID]) != 0)
6182 rc = container_adupdate(ldap_handle, dn_path, dName, "", count, av);
6183 }
6184
6185 return(rc);
6186}
6187
6188int container_update(LDAP *ldap_handle, char *dn_path, int beforec,
6189 char **before, int afterc, char **after)
6190{
6191 char distinguishedName[256];
6192 int rc;
6193
6194 memset(distinguishedName, '\0', sizeof(distinguishedName));
6195
6196 if (rc = container_get_distinguishedName(ldap_handle, dn_path,
6197 distinguishedName, afterc, after))
6198 return(rc);
6199
6200 if (strlen(distinguishedName) == 0)
6201 {
6202 rc = container_create(ldap_handle, dn_path, afterc, after);
6203 return(rc);
6204 }
6205
6206 container_check(ldap_handle, dn_path, after[CONTAINER_NAME]);
6207 rc = container_adupdate(ldap_handle, dn_path, "", distinguishedName, afterc,
6208 after);
6209
6210 return(rc);
6211}
6212
6213int container_get_distinguishedName(LDAP *ldap_handle, char *dn_path,
6214 char *distinguishedName, int count,
6215 char **av)
6216{
6217 char *attr_array[3];
6218 LK_ENTRY *group_base;
6219 int group_count;
6220 char dName[256];
6221 char cName[256];
6222 char filter[512];
6223 int rc;
6224
6225 memset(filter, '\0', sizeof(filter));
6226 memset(dName, '\0', sizeof(dName));
6227 memset(cName, '\0', sizeof(cName));
6228 container_get_dn(av[CONTAINER_NAME], dName);
6229 container_get_name(av[CONTAINER_NAME], cName);
6230
6231 if (strlen(dName) == 0)
6232 {
6233 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
6234 av[CONTAINER_NAME]);
6235 return(AD_INVALID_NAME);
6236 }
6237
6238 if (!check_container_name(cName))
6239 {
6240 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
6241 cName);
6242 return(AD_INVALID_NAME);
6243 }
6244
6245 sprintf(filter, "(&(objectClass=organizationalUnit)(mitMoiraId=%s))",
6246 av[CONTAINER_ROWID]);
6247 attr_array[0] = "distinguishedName";
6248 attr_array[1] = NULL;
6249 group_count = 0;
6250 group_base = NULL;
6251
6252 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6253 &group_base, &group_count,
6254 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
6255 {
6256 if (group_count == 1)
6257 {
6258 strcpy(distinguishedName, group_base->value);
6259 }
6260
6261 linklist_free(group_base);
6262 group_base = NULL;
6263 group_count = 0;
6264 }
6265
6266 if (strlen(distinguishedName) == 0)
6267 {
6268 sprintf(filter, "(&(objectClass=organizationalUnit)"
6269 "(distinguishedName=%s,%s))", dName, dn_path);
6270 attr_array[0] = "distinguishedName";
6271 attr_array[1] = NULL;
6272 group_count = 0;
6273 group_base = NULL;
6274
6275 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6276 &group_base, &group_count,
6277 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
6278 {
6279 if (group_count == 1)
6280 {
6281 strcpy(distinguishedName, group_base->value);
6282 }
6283
6284 linklist_free(group_base);
6285 group_base = NULL;
6286 group_count = 0;
6287 }
6288 }
6289
6290 return(0);
6291}
6292
6293int container_adupdate(LDAP *ldap_handle, char *dn_path, char *dName,
6294 char *distinguishedName, int count, char **av)
6295{
6296 char *attr_array[5];
6297 LK_ENTRY *group_base;
6298 LK_ENTRY *pPtr;
6299 LDAPMod *mods[20];
6300 int group_count;
6301 char filter[512];
6302 char *moiraId_v[] = {NULL, NULL};
6303 char *desc_v[] = {NULL, NULL};
6304 char *managedBy_v[] = {NULL, NULL};
6305 char managedByDN[256];
6306 char moiraId[64];
6307 char desc[256];
6308 char ad_path[512];
6309 int rc;
6310 int i;
6311 int n;
6312
6313
6314 strcpy(ad_path, distinguishedName);
6315
6316 if (strlen(dName) != 0)
6317 sprintf(ad_path, "%s,%s", dName, dn_path);
6318
6319 sprintf(filter, "(&(objectClass=organizationalUnit)(distinguishedName=%s))",
6320 ad_path);
6321
6322 if (strlen(av[CONTAINER_ID]) != 0)
6323 sprintf(filter, "(&(objectClass=organizationalUnit)(mitMoiraId=%s))",
6324 av[CONTAINER_ROWID]);
6325
6326 attr_array[0] = "mitMoiraId";
6327 attr_array[1] = "description";
6328 attr_array[2] = "managedBy";
6329 attr_array[3] = NULL;
6330 group_count = 0;
6331 group_base = NULL;
6332
6333 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6334 &group_base, &group_count,
6335 LDAP_SCOPE_SUBTREE)) != LDAP_SUCCESS)
6336 {
6337 com_err(whoami, 0, "Unable to retreive container info for %s : %s",
6338 av[CONTAINER_NAME], ldap_err2string(rc));
6339 return(rc);
6340 }
6341
6342 memset(managedByDN, '\0', sizeof(managedByDN));
6343 memset(moiraId, '\0', sizeof(moiraId));
6344 memset(desc, '\0', sizeof(desc));
6345 pPtr = group_base;
6346
6347 while (pPtr)
6348 {
6349 if (!strcasecmp(pPtr->attribute, "description"))
6350 strcpy(desc, pPtr->value);
6351 else if (!strcasecmp(pPtr->attribute, "managedBy"))
6352 strcpy(managedByDN, pPtr->value);
6353 else if (!strcasecmp(pPtr->attribute, "mitMoiraId"))
6354 strcpy(moiraId, pPtr->value);
6355 pPtr = pPtr->next;
6356 }
6357
6358 linklist_free(group_base);
6359 group_base = NULL;
6360 group_count = 0;
6361
6362 n = 0;
6363 if (strlen(av[CONTAINER_ROWID]) != 0)
6364 {
6365 moiraId_v[0] = av[CONTAINER_ROWID];
6366 ADD_ATTR("mitMoiraId", moiraId_v, LDAP_MOD_REPLACE);
6367 }
6368
6369 if (strlen(av[CONTAINER_DESC]) != 0)
6370 {
6371 attribute_update(ldap_handle, ad_path, av[CONTAINER_DESC], "description",
6372 dName);
6373 }
6374 else
6375 {
6376 if (strlen(desc) != 0)
6377 {
6378 attribute_update(ldap_handle, ad_path, "", "description", dName);
6379 }
6380 }
6381
6382 if ((strlen(av[CONTAINER_TYPE]) != 0) && (strlen(av[CONTAINER_ID]) != 0))
6383 {
6384 if (!strcasecmp(av[CONTAINER_TYPE], "KERBEROS"))
6385 {
6386 if (!contact_create(ldap_handle, dn_path, av[CONTAINER_ID],
6387 kerberos_ou))
6388 {
6389 sprintf(managedByDN, "CN=%s,%s,%s", av[CONTAINER_ID],
6390 kerberos_ou, dn_path);
6391 managedBy_v[0] = managedByDN;
6392 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_REPLACE);
6393 }
6394 else
6395 {
6396 if (strlen(managedByDN) != 0)
6397 {
6398 attribute_update(ldap_handle, ad_path, "", "managedBy",
6399 dName);
6400 }
6401 }
6402 }
6403 else
6404 {
6405 memset(filter, '\0', sizeof(filter));
6406
6407 if (!strcasecmp(av[CONTAINER_TYPE], "USER"))
6408 {
6409 sprintf(filter, "(&(cn=%s)(&(objectCategory=person)"
6410 "(objectClass=user)))", av[CONTAINER_ID]);
6411 }
6412
6413 if (!strcasecmp(av[CONTAINER_TYPE], "LIST"))
6414 {
6415 sprintf(filter, "(&(objectClass=group)(cn=%s))",
6416 av[CONTAINER_ID]);
6417 }
6418
6419 if (strlen(filter) != 0)
6420 {
6421 attr_array[0] = "distinguishedName";
6422 attr_array[1] = NULL;
6423 group_count = 0;
6424 group_base = NULL;
6425 if ((rc = linklist_build(ldap_handle, dn_path, filter,
6426 attr_array, &group_base, &group_count,
6427 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
6428 {
6429 if (group_count == 1)
6430 {
6431 strcpy(managedByDN, group_base->value);
6432 managedBy_v[0] = managedByDN;
6433 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_REPLACE);
6434 }
6435 else
6436 {
6437 if (strlen(managedByDN) != 0)
6438 {
6439 attribute_update(ldap_handle, ad_path, "",
6440 "managedBy", dName);
6441 }
6442 }
6443
6444 linklist_free(group_base);
6445 group_base = NULL;
6446 group_count = 0;
6447 }
6448 }
6449 else
6450 {
6451 if (strlen(managedByDN) != 0)
6452 {
6453 attribute_update(ldap_handle, ad_path, "", "managedBy",
6454 dName);
6455 }
6456 }
6457 }
6458 }
6459
6460 mods[n] = NULL;
6461
6462 if (n == 0)
6463 return(LDAP_SUCCESS);
6464
6465 rc = ldap_modify_s(ldap_handle, ad_path, mods);
6466
6467 for (i = 0; i < n; i++)
6468 free(mods[i]);
6469
6470 if (rc != LDAP_SUCCESS)
6471 {
6472 com_err(whoami, 0, "Unable to modify container info for %s : %s",
6473 av[CONTAINER_NAME], ldap_err2string(rc));
6474 return(rc);
6475 }
6476
6477 return(rc);
6478}
6479
6480int container_move_objects(LDAP *ldap_handle, char *dn_path, char *dName)
6481{
6482 char *attr_array[3];
6483 LK_ENTRY *group_base;
6484 LK_ENTRY *pPtr;
6485 int group_count;
6486 char filter[512];
6487 char new_cn[128];
6488 char temp[256];
6489 int rc;
6490 int NumberOfEntries = 10;
6491 int i;
6492 int count;
6493
6494 rc = ldap_set_option(ldap_handle, LDAP_OPT_SIZELIMIT, &NumberOfEntries);
6495
6496 for (i = 0; i < 3; i++)
6497 {
6498 memset(filter, '\0', sizeof(filter));
6499
6500 if (i == 0)
6501 {
6502 strcpy(filter, "(!(|(objectClass=computer)"
6503 "(objectClass=organizationalUnit)))");
6504 attr_array[0] = "cn";
6505 attr_array[1] = NULL;
6506 }
6507 else if (i == 1)
6508 {
6509 strcpy(filter, "(objectClass=computer)");
6510 attr_array[0] = "cn";
6511 attr_array[1] = NULL;
6512 }
6513 else
6514 {
6515 strcpy(filter, "(objectClass=organizationalUnit)");
6516 attr_array[0] = "ou";
6517 attr_array[1] = NULL;
6518 }
6519
6520 while (1)
6521 {
6522 if ((rc = linklist_build(ldap_handle, dName, filter, attr_array,
6523 &group_base, &group_count,
6524 LDAP_SCOPE_SUBTREE)) != LDAP_SUCCESS)
6525 {
6526 break;
6527 }
6528
6529 if (group_count == 0)
6530 break;
6531
6532 pPtr = group_base;
6533
6534 while(pPtr)
6535 {
6536 if (!strcasecmp(pPtr->attribute, "cn"))
6537 {
6538 sprintf(new_cn, "cn=%s", pPtr->value);
6539 if (i == 0)
6540 sprintf(temp, "%s,%s", orphans_other_ou, dn_path);
6541 if (i == 1)
6542 sprintf(temp, "%s,%s", orphans_machines_ou, dn_path);
6543 count = 1;
6544
6545 while (1)
6546 {
6547 rc = ldap_rename_s(ldap_handle, pPtr->dn, new_cn, temp,
6548 TRUE, NULL, NULL);
6549 if (rc == LDAP_ALREADY_EXISTS)
6550 {
6551 sprintf(new_cn, "cn=%s_%d", pPtr->value, count);
6552 ++count;
6553 }
6554 else
6555 break;
6556 }
6557 }
6558 else if (!strcasecmp(pPtr->attribute, "ou"))
6559 {
6560 rc = ldap_delete_s(ldap_handle, pPtr->dn);
6561 }
6562
6563 pPtr = pPtr->next;
6564 }
6565
6566 linklist_free(group_base);
6567 group_base = NULL;
6568 group_count = 0;
6569 }
6570 }
6571
6572 return(0);
6573}
6574
6575int get_machine_ou(LDAP *ldap_handle, char *dn_path, char *member,
6576 char *machine_ou, char *NewMachineName)
6577{
6578 LK_ENTRY *group_base;
6579 int group_count;
6580 int i;
6581 char filter[128];
6582 char *attr_array[3];
6583 char cn[256];
6584 char dn[256];
6585 char temp[256];
6586 char *pPtr;
6587 int rc;
6588
6589 strcpy(NewMachineName, member);
6590 rc = moira_connect();
6591 rc = GetMachineName(NewMachineName);
6592 moira_disconnect();
6593
6594 if (strlen(NewMachineName) == 0)
6595 {
6596 com_err(whoami, 0, "Unable to find alais for machine %s in Moira",
6597 member);
6598 return(1);
6599 }
6600
6601 pPtr = NULL;
6602 pPtr = strchr(NewMachineName, '.');
6603
6604 if (pPtr != NULL)
6605 (*pPtr) = '\0';
6606
6607 group_base = NULL;
6608 group_count = 0;
6609 sprintf(filter, "(sAMAccountName=%s$)", NewMachineName);
6610 attr_array[0] = "cn";
6611 attr_array[1] = NULL;
6612 sprintf(temp, "%s", dn_path);
6613
6614 if ((rc = linklist_build(ldap_handle, temp, filter, attr_array,
6615 &group_base, &group_count,
6616 LDAP_SCOPE_SUBTREE)) != 0)
6617 {
6618 com_err(whoami, 0, "Unable to process machine %s : %s",
6619 member, ldap_err2string(rc));
6620 return(1);
6621 }
6622
6623 if (group_count != 1)
6624 {
6625 com_err(whoami, 0,
6626 "Unable to process machine %s : machine not found in AD",
6627 NewMachineName);
6628 return(1);
6629 }
6630
6631 strcpy(dn, group_base->dn);
6632 strcpy(cn, group_base->value);
6633
6634 for (i = 0; i < (int)strlen(dn); i++)
6635 dn[i] = tolower(dn[i]);
6636
6637 for (i = 0; i < (int)strlen(cn); i++)
6638 cn[i] = tolower(cn[i]);
6639
6640 linklist_free(group_base);
6641 pPtr = NULL;
6642 pPtr = strstr(dn, cn);
6643
6644 if (pPtr == NULL)
6645 {
6646 com_err(whoami, 0, "Unable to process machine %s",
6647 member);
6648 return(1);
6649 }
6650
6651 pPtr += strlen(cn) + 1;
6652 strcpy(machine_ou, pPtr);
6653 pPtr = NULL;
6654 pPtr = strstr(machine_ou, "dc=");
6655
6656 if (pPtr == NULL)
6657 {
6658 com_err(whoami, 0, "Unable to process machine %s",
6659 member);
6660 return(1);
6661 }
6662
6663 --pPtr;
6664 (*pPtr) = '\0';
6665
6666 return(0);
6667}
6668
6669int machine_move_to_ou(LDAP *ldap_handle, char * dn_path,
6670 char *MoiraMachineName, char *DestinationOu)
6671{
6672 char NewCn[128];
6673 char OldDn[512];
6674 char MachineName[128];
6675 char filter[128];
6676 char *attr_array[3];
6677 char NewOu[256];
6678 char *cPtr = NULL;
6679 int group_count;
6680 long rc;
6681 LK_ENTRY *group_base;
6682
6683 group_count = 0;
6684 group_base = NULL;
6685
6686 strcpy(MachineName, MoiraMachineName);
6687 rc = GetMachineName(MachineName);
6688
6689 if (strlen(MachineName) == 0)
6690 {
6691 com_err(whoami, 0, "Unable to find alais for machine %s in Moira",
6692 MoiraMachineName);
6693 return(1);
6694 }
6695
6696 cPtr = strchr(MachineName, '.');
6697
6698 if (cPtr != NULL)
6699 (*cPtr) = '\0';
6700
6701 sprintf(filter, "(sAMAccountName=%s$)", MachineName);
6702 attr_array[0] = "sAMAccountName";
6703 attr_array[1] = NULL;
6704
6705 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6706 &group_base,
6707 &group_count, LDAP_SCOPE_SUBTREE)) != 0)
6708 {
6709 com_err(whoami, 0, "Unable to process machine %s : %s",
6710 MoiraMachineName, ldap_err2string(rc));
6711 return(1);
6712 }
6713
6714 if (group_count == 1)
6715 strcpy(OldDn, group_base->dn);
6716
6717 linklist_free(group_base);
6718 group_base = NULL;
6719
6720 if (group_count != 1)
6721 {
6722 com_err(whoami, 0, "Unable to find machine %s in AD: %s",
6723 MoiraMachineName);
6724 return(1);
6725 }
6726
6727 sprintf(NewOu, "%s,%s", DestinationOu, dn_path);
6728 cPtr = strchr(OldDn, ',');
6729
6730 if (cPtr != NULL)
6731 {
6732 ++cPtr;
6733 if (!strcasecmp(cPtr, NewOu))
6734 return(0);
6735 }
6736
6737 sprintf(NewCn, "CN=%s", MachineName);
6738 rc = ldap_rename_s(ldap_handle, OldDn, NewCn, NewOu, TRUE, NULL, NULL);
6739
6740 return(rc);
6741}
6742
6743int machine_check(LDAP *ldap_handle, char *dn_path, char *machine_name)
6744{
6745 char Name[128];
6746 char *pPtr;
6747 int rc;
6748
6749 memset(Name, '\0', sizeof(Name));
6750 strcpy(Name, machine_name);
6751 pPtr = NULL;
6752 pPtr = strchr(Name, '.');
6753
6754 if (pPtr != NULL)
6755 (*pPtr) = '\0';
6756
6757 strcat(Name, "$");
6758 return(!(rc = checkADname(ldap_handle, dn_path, Name)));
6759}
6760
6761int machine_get_moira_container(LDAP *ldap_handle, char *dn_path,
6762 char *machine_name, char *container_name)
6763{
6764 int rc;
6765 char *av[2];
6766 char *call_args[2];
6767
6768 av[0] = machine_name;
6769 call_args[0] = (char *)container_name;
6770 rc = mr_query("get_machine_to_container_map", 1, av,
6771 machine_GetMoiraContainer, call_args);
6772 return(rc);
6773}
6774
6775int machine_GetMoiraContainer(int ac, char **av, void *ptr)
6776{
6777 char **call_args;
6778
6779 call_args = ptr;
6780 strcpy(call_args[0], av[1]);
6781 return(0);
6782}
6783
6784int Moira_container_group_create(char **after)
6785{
6786 long rc;
6787 char GroupName[64];
6788 char *argv[20];
6789
6790 memset(GroupName, '\0', sizeof(GroupName));
6791 rc = Moira_groupname_create(GroupName, after[CONTAINER_NAME],
6792 after[CONTAINER_ROWID]);
6793 if (rc)
6794 return rc;
6795
6796 argv[L_NAME] = GroupName;
6797 argv[L_ACTIVE] = "1";
6798 argv[L_PUBLIC] = "0";
6799 argv[L_HIDDEN] = "0";
6800 argv[L_MAILLIST] = "0";
6801 argv[L_GROUP] = "1";
6802 argv[L_GID] = UNIQUE_GID;
6803 argv[L_NFSGROUP] = "0";
6804 argv[L_MAILMAN] = "0";
6805 argv[L_MAILMAN_SERVER] = "[NONE]";
6806 argv[L_DESC] = "auto created container group";
6807 argv[L_ACE_TYPE] = "USER";
6808 argv[L_MEMACE_TYPE] = "USER";
6809 argv[L_ACE_NAME] = "sms";
6810 argv[L_MEMACE_NAME] = "sms";
6811
6812 if (rc = mr_query("add_list", 15, argv, NULL, NULL))
6813 {
6814 com_err(whoami, 0,
6815 "Unable to create container group %s for container %s: %s",
6816 GroupName, after[CONTAINER_NAME], error_message(rc));
6817 }
6818
6819 Moira_setContainerGroup(after[CONTAINER_NAME], GroupName);
6820 Moira_addGroupToParent(after[CONTAINER_NAME], GroupName);
6821
6822 return(rc);
6823}
6824
6825int Moira_container_group_update(char **before, char **after)
6826{
6827 long rc;
6828 char BeforeGroupName[64];
6829 char AfterGroupName[64];
6830 char *argv[20];
6831
6832 if (!strcasecmp(after[CONTAINER_NAME], before[CONTAINER_NAME]))
6833 return(0);
6834
6835 memset(BeforeGroupName, '\0', sizeof(BeforeGroupName));
6836 Moira_getGroupName(after[CONTAINER_NAME], BeforeGroupName, 0);
6837 if (strlen(BeforeGroupName) == 0)
6838 return(0);
6839
6840 memset(AfterGroupName, '\0', sizeof(AfterGroupName));
6841 rc = Moira_groupname_create(AfterGroupName, after[CONTAINER_NAME],
6842 after[CONTAINER_ROWID]);
6843 if (rc)
6844 return rc;
6845
6846 if (strcasecmp(BeforeGroupName, AfterGroupName))
6847 {
6848 argv[L_NAME] = BeforeGroupName;
6849 argv[L_NAME + 1] = AfterGroupName;
6850 argv[L_ACTIVE + 1] = "1";
6851 argv[L_PUBLIC + 1] = "0";
6852 argv[L_HIDDEN + 1] = "0";
6853 argv[L_MAILLIST + 1] = "0";
6854 argv[L_GROUP + 1] = "1";
6855 argv[L_GID + 1] = UNIQUE_GID;
6856 argv[L_NFSGROUP + 1] = "0";
6857 argv[L_MAILMAN + 1] = "0";
6858 argv[L_MAILMAN_SERVER + 1] = "[NONE]";
6859 argv[L_DESC + 1] = "auto created container group";
6860 argv[L_ACE_TYPE + 1] = "USER";
6861 argv[L_MEMACE_TYPE + 1] = "USER";
6862 argv[L_ACE_NAME + 1] = "sms";
6863 argv[L_MEMACE_NAME + 1] = "sms";
6864
6865 if (rc = mr_query("update_list", 16, argv, NULL, NULL))
6866 {
6867 com_err(whoami, 0,
6868 "Unable to rename container group from %s to %s: %s",
6869 BeforeGroupName, AfterGroupName, error_message(rc));
6870 }
6871 }
6872
6873 return(rc);
6874}
6875
6876int Moira_container_group_delete(char **before)
6877{
6878 long rc = 0;
6879 char *argv[13];
6880 char GroupName[64];
6881 char ParentGroupName[64];
6882
6883 memset(ParentGroupName, '\0', sizeof(ParentGroupName));
6884 Moira_getGroupName(before[CONTAINER_NAME], ParentGroupName, 1);
6885
6886 memset(GroupName, '\0', sizeof(GroupName));
6887
6888 if (strcmp(before[CONTAINER_GROUP_NAME], "[none]"))
6889 strcpy(GroupName, before[CONTAINER_GROUP_NAME]);
6890
6891 if ((strlen(ParentGroupName) != 0) && (strlen(GroupName) != 0))
6892 {
6893 argv[0] = ParentGroupName;
6894 argv[1] = "LIST";
6895 argv[2] = GroupName;
6896
6897 if (rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL))
6898 {
6899 com_err(whoami, 0,
6900 "Unable to delete container group %s from list: %s",
6901 GroupName, ParentGroupName, error_message(rc));
6902 }
6903 }
6904
6905 if (strlen(GroupName) != 0)
6906 {
6907 argv[0] = GroupName;
6908
6909 if (rc = mr_query("delete_list", 1, argv, NULL, NULL))
6910 {
6911 com_err(whoami, 0, "Unable to delete container group %s : %s",
6912 GroupName, error_message(rc));
6913 }
6914 }
6915
6916 return(rc);
6917}
6918
6919int Moira_groupname_create(char *GroupName, char *ContainerName,
6920 char *ContainerRowID)
6921{
6922 char *ptr;
6923 char *ptr1;
6924 char temp[64];
6925 char newGroupName[64];
6926 char tempGroupName[64];
6927 char tempgname[64];
6928 char *argv[1];
6929 int i;
6930 long rc;
6931
6932 strcpy(temp, ContainerName);
6933
6934 ptr1 = strrchr(temp, '/');
6935
6936 if (ptr1 != NULL)
6937 {
6938 *ptr1 = '\0';
6939 ptr = ++ptr1;
6940 ptr1 = strrchr(temp, '/');
6941
6942 if (ptr1 != NULL)
6943 {
6944 sprintf(tempgname, "%s-%s", ++ptr1, ptr);
6945 }
6946 else
6947 strcpy(tempgname, ptr);
6948 }
6949 else
6950 strcpy(tempgname, temp);
6951
6952 if (strlen(tempgname) > 25)
6953 tempgname[25] ='\0';
6954
6955 sprintf(newGroupName, "cnt-%s", tempgname);
6956
6957 /* change everything to lower case */
6958 ptr = newGroupName;
6959
6960 while (*ptr)
6961 {
6962 if (isupper(*ptr))
6963 *ptr = tolower(*ptr);
6964
6965 if (*ptr == ' ')
6966 *ptr = '-';
6967
6968 ptr++;
6969 }
6970
6971 strcpy(tempGroupName, newGroupName);
6972 i = (int)'0';
6973
6974 /* append 0-9 then a-z if a duplicate is found */
6975 while(1)
6976 {
6977 argv[0] = newGroupName;
6978
6979 if (rc = mr_query("get_list_info", 1, argv, NULL, NULL))
6980 {
6981 if (rc == MR_NO_MATCH)
6982 break;
6983 com_err(whoami, 0, "Moira error while creating group name for "
6984 "container %s : %s", ContainerName, error_message(rc));
6985 return rc;
6986 }
6987
6988 sprintf(newGroupName, "%s-%c", tempGroupName, i);
6989
6990 if (i == (int)'z')
6991 {
6992 com_err(whoami, 0, "Unable to find a unique group name for "
6993 "container %s: too many duplicate container names",
6994 ContainerName);
6995 return 1;
6996 }
6997
6998 if (i == '9')
6999 i = 'a';
7000 else
7001 i++;
7002 }
7003
7004 strcpy(GroupName, newGroupName);
7005 return(0);
7006}
7007
7008int Moira_setContainerGroup(char *origContainerName, char *GroupName)
7009{
7010 long rc;
7011 char *argv[3];
7012
7013 argv[0] = origContainerName;
7014 argv[1] = GroupName;
7015
7016 if ((rc = mr_query("set_container_list", 2, argv, NULL, NULL)))
7017 {
7018 com_err(whoami, 0,
7019 "Unable to set container group %s in container %s: %s",
7020 GroupName, origContainerName, error_message(rc));
7021 }
7022
7023 return(0);
7024}
7025
7026int Moira_addGroupToParent(char *origContainerName, char *GroupName)
7027 {
7028 char ContainerName[64];
7029 char ParentGroupName[64];
7030 char *argv[3];
7031 long rc;
7032
7033 strcpy(ContainerName, origContainerName);
7034
7035 Moira_getGroupName(ContainerName, ParentGroupName, 1);
7036
7037 /* top-level container */
7038 if (strlen(ParentGroupName) == 0)
7039 return(0);
7040
7041 argv[0] = ParentGroupName;
7042 argv[1] = "LIST";
7043 argv[2] = GroupName;
7044
7045 if ((rc = mr_query("add_member_to_list", 3, argv, NULL, NULL)))
7046 {
7047 com_err(whoami, 0,
7048 "Unable to add container group %s to parent group %s: %s",
7049 GroupName, ParentGroupName, error_message(rc));
7050 }
7051
7052 return(0);
7053 }
7054
7055int Moira_getContainerGroup(int ac, char **av, void *ptr)
7056{
7057 char **call_args;
7058
7059 call_args = ptr;
7060 strcpy(call_args[0], av[1]);
7061
7062 return(0);
7063}
7064
7065int Moira_getGroupName(char *origContainerName, char *GroupName,
7066 int ParentFlag)
7067{
7068 char ContainerName[64];
7069 char *argv[3];
7070 char *call_args[3];
7071 char *ptr;
7072 long rc;
7073
7074 strcpy(ContainerName, origContainerName);
7075
7076 if (ParentFlag)
7077 {
7078 ptr = strrchr(ContainerName, '/');
7079
7080 if (ptr != NULL)
7081 (*ptr) = '\0';
7082 else
7083 return(0);
7084 }
7085
7086 argv[0] = ContainerName;
7087 argv[1] = NULL;
7088 call_args[0] = GroupName;
7089 call_args[1] = NULL;
7090
7091 if (!(rc = mr_query("get_container_list", 1, argv, Moira_getContainerGroup,
7092 call_args)))
7093 {
7094 if (strlen(GroupName) != 0)
7095 return(0);
7096 }
7097
7098 if (rc)
7099 com_err(whoami, 0, "Unable to get container group from container %s: %s",
7100 ContainerName, error_message(rc));
7101 else
7102 com_err(whoami, 0, "Unable to get container group from container %s",
7103 ContainerName);
7104
7105 return(0);
7106}
7107
7108int Moira_process_machine_container_group(char *MachineName, char* GroupName,
7109 int DeleteMachine)
7110{
7111 char *argv[3];
7112 long rc;
7113
7114 if (strcmp(GroupName, "[none]") == 0)
7115 return 0;
7116
7117 argv[0] = GroupName;
7118 argv[1] = "MACHINE";
7119 argv[2] = MachineName;
7120
7121 if (!DeleteMachine)
7122 rc = mr_query("add_member_to_list", 3, argv, NULL, NULL);
7123 else
7124 rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL);
7125
7126 if (rc)
7127 {
7128 com_err(whoami, 0, "Unable to add machine %s to container group%s: %s",
7129 MachineName, GroupName, error_message(rc));
7130 }
7131
7132 return(0);
7133}
7134
7135int GetMachineName(char *MachineName)
7136{
7137 char *args[2];
7138 char NewMachineName[1024];
7139 char *szDot;
7140 int rc = 0;
7141 int i;
7142 DWORD dwLen = 0;
7143 char *call_args[2];
7144
7145 // If the address happens to be in the top-level MIT domain, great!
7146 strcpy(NewMachineName, MachineName);
7147
7148 for (i = 0; i < (int)strlen(NewMachineName); i++)
7149 NewMachineName[i] = toupper(NewMachineName[i]);
7150
7151 szDot = strchr(NewMachineName,'.');
7152
7153 if ((szDot) && (!strcasecmp(szDot+1, DOMAIN_SUFFIX)))
7154 {
7155 return(0);
7156 }
7157
7158 // If not, see if it has a Moira alias in the top-level MIT domain.
7159 memset(NewMachineName, '\0', sizeof(NewMachineName));
7160 args[0] = "*";
7161 args[1] = MachineName;
7162 call_args[0] = NewMachineName;
7163 call_args[1] = NULL;
7164
7165 if (rc = mr_query("get_hostalias", 2, args, ProcessMachineName, call_args))
7166 {
7167 com_err(whoami, 0, "Unable to resolve machine name %s : %s",
7168 MachineName, error_message(rc));
7169 strcpy(MachineName, "");
7170 return(0);
7171 }
7172
7173 if (strlen(NewMachineName) != 0)
7174 strcpy(MachineName, NewMachineName);
7175 else
7176 strcpy(MachineName, "");
7177
7178 return(0);
7179}
7180
7181int ProcessMachineName(int ac, char **av, void *ptr)
7182{
7183 char **call_args;
7184 char MachineName[1024];
7185 char *szDot;
7186 int i;
7187
7188 call_args = ptr;
7189
7190 if (strlen(call_args[0]) == 0)
7191 {
7192 strcpy(MachineName, av[0]);
7193
7194 for (i = 0; i < (int)strlen(MachineName); i++)
7195 MachineName[i] = toupper(MachineName[i]);
7196
7197 szDot = strchr(MachineName,'.');
7198
7199 if ((szDot) && (!strcasecmp(szDot+1,DOMAIN_SUFFIX)))
7200 {
7201 strcpy(call_args[0], MachineName);
7202 }
7203 }
7204
7205 return(0);
7206}
7207
7208void SwitchSFU(LDAPMod **mods, int *UseSFU30, int n)
7209{
7210 int i;
7211
7212 if (*UseSFU30)
7213 {
7214 for (i = 0; i < n; i++)
7215 {
7216 if (!strcmp(mods[i]->mod_type, "msSFU30UidNumber"))
7217 mods[i]->mod_type = "uidNumber";
7218 }
7219
7220 (*UseSFU30) = 0;
7221 }
7222 else
7223 {
7224 for (i = 0; i < n; i++)
7225 {
7226 if (!strcmp(mods[i]->mod_type, "uidNumber"))
7227 mods[i]->mod_type = "msSFU30UidNumber";
7228 }
7229
7230 (*UseSFU30) = 1;
7231 }
7232}
7233
7234int SetHomeDirectory(LDAP *ldap_handle, char *user_name,
7235 char *DistinguishedName,
7236 char *WinHomeDir, char *WinProfileDir,
7237 char **homedir_v, char **winProfile_v,
7238 char **drives_v, LDAPMod **mods,
7239 int OpType, int n)
7240{
7241 char **hp;
7242 char cWeight[3];
7243 char cPath[1024];
7244 char path[1024];
7245 char winPath[1024];
7246 char winProfile[1024];
7247 char homeDrive[8];
7248 int last_weight;
7249 int i;
7250 int rc;
7251 LDAPMod *DelMods[20];
7252
7253 memset(homeDrive, '\0', sizeof(homeDrive));
7254 memset(path, '\0', sizeof(path));
7255 memset(winPath, '\0', sizeof(winPath));
7256 memset(winProfile, '\0', sizeof(winProfile));
7257 hp = NULL;
7258
7259 if ((!strcasecmp(WinHomeDir, "[afs]")) ||
7260 (!strcasecmp(WinProfileDir, "[afs]")))
7261 {
7262 if ((hp = hes_resolve(user_name, "filsys")) != NULL)
7263 {
7264 memset(cWeight, 0, sizeof(cWeight));
7265 memset(cPath, 0, sizeof(cPath));
7266 last_weight = 1000;
7267 i = 0;
7268
7269 while (hp[i] != NULL)
7270 {
7271 if (sscanf(hp[i], "%*s %s", cPath))
7272 {
7273 if (strnicmp(cPath, AFS, strlen(AFS)) == 0)
7274 {
7275 if (sscanf(hp[i], "%*s %*s %*s %*s %s", cWeight))
7276 {
7277 if (atoi(cWeight) < last_weight)
7278 {
7279 strcpy(path, cPath);
7280 last_weight = (int)atoi(cWeight);
7281 }
7282 }
7283 else
7284 strcpy(path, cPath);
7285 }
7286 }
7287 ++i;
7288 }
7289
7290 if (strlen(path))
7291 {
7292 if (!strnicmp(path, AFS, strlen(AFS)))
7293 {
7294 AfsToWinAfs(path, winPath);
7295 strcpy(winProfile, winPath);
7296 strcat(winProfile, "\\.winprofile");
7297 }
7298 }
7299 }
7300 else
7301 return(n);
7302 }
7303
7304 if ((!strcasecmp(WinHomeDir, "[dfs]")) ||
7305 (!strcasecmp(WinProfileDir, "[dfs]")))
7306 {
7307 sprintf(path, "\\\\%s\\dfs\\profiles\\%c\\%s", ldap_domain,
7308 user_name[0], user_name);
7309
7310 if (!strcasecmp(WinProfileDir, "[dfs]"))
7311 {
7312 strcpy(winProfile, path);
7313 strcat(winProfile, "\\.winprofile");
7314 }
7315
7316 if (!strcasecmp(WinHomeDir, "[dfs]"))
7317 strcpy(winPath, path);
7318 }
7319
7320 if (hp != NULL)
7321 {
7322 i = 0;
7323 while (hp[i])
7324 {
7325 free(hp[i]);
7326 i++;
7327 }
7328 }
7329
7330 if (!strcasecmp(WinHomeDir, "[local]"))
7331 memset(winPath, '\0', sizeof(winPath));
7332 else if (!strcasecmp(WinHomeDir, "[afs]") ||
7333 !strcasecmp(WinHomeDir, "[dfs]"))
7334 {
7335 strcpy(homeDrive, "H:");
7336 }
7337 else
7338 {
7339 strcpy(winPath, WinHomeDir);
7340 if (!strncmp(WinHomeDir, "\\\\", 2))
7341 {
7342 strcpy(homeDrive, "H:");
7343 }
7344 }
7345
7346 // nothing needs to be done if WinProfileDir is [afs].
7347 if (!strcasecmp(WinProfileDir, "[local]"))
7348 memset(winProfile, '\0', sizeof(winProfile));
7349 else if (strcasecmp(WinProfileDir, "[afs]") &&
7350 strcasecmp(WinProfileDir, "[dfs]"))
7351 {
7352 strcpy(winProfile, WinProfileDir);
7353 }
7354
7355 if (strlen(winProfile) != 0)
7356 {
7357 if (winProfile[strlen(winProfile) - 1] == '\\')
7358 winProfile[strlen(winProfile) - 1] = '\0';
7359 }
7360
7361 if (strlen(winPath) != 0)
7362 {
7363 if (winPath[strlen(winPath) - 1] == '\\')
7364 winPath[strlen(winPath) - 1] = '\0';
7365 }
7366
7367 if ((winProfile[1] == ':') && (strlen(winProfile) == 2))
7368 strcat(winProfile, "\\");
7369
7370 if ((winPath[1] == ':') && (strlen(winPath) == 2))
7371 strcat(winPath, "\\");
7372
7373 if (strlen(winPath) == 0)
7374 {
7375 if (OpType == LDAP_MOD_REPLACE)
7376 {
7377 i = 0;
7378 DEL_ATTR("homeDirectory", LDAP_MOD_DELETE);
7379 DelMods[i] = NULL;
7380 //unset homeDirectory attribute for user.
7381 rc = ldap_modify_s(ldap_handle, DistinguishedName, DelMods);
7382 free(DelMods[0]);
7383 }
7384 }
7385 else
7386 {
7387 homedir_v[0] = strdup(winPath);
7388 ADD_ATTR("homeDirectory", homedir_v, OpType);
7389 }
7390
7391 if (strlen(winProfile) == 0)
7392 {
7393 if (OpType == LDAP_MOD_REPLACE)
7394 {
7395 i = 0;
7396 DEL_ATTR("profilePath", LDAP_MOD_DELETE);
7397 DelMods[i] = NULL;
7398 //unset profilePate attribute for user.
7399 rc = ldap_modify_s(ldap_handle, DistinguishedName, DelMods);
7400 free(DelMods[0]);
7401 }
7402 }
7403 else
7404 {
7405 winProfile_v[0] = strdup(winProfile);
7406 ADD_ATTR("profilePath", winProfile_v, OpType);
7407 }
7408
7409 if (strlen(homeDrive) == 0)
7410 {
7411 if (OpType == LDAP_MOD_REPLACE)
7412 {
7413 i = 0;
7414 DEL_ATTR("homeDrive", LDAP_MOD_DELETE);
7415 DelMods[i] = NULL;
7416 //unset homeDrive attribute for user
7417 rc = ldap_modify_s(ldap_handle, DistinguishedName, DelMods);
7418 free(DelMods[0]);
7419 }
7420 }
7421 else
7422 {
7423 drives_v[0] = strdup(homeDrive);
7424 ADD_ATTR("homeDrive", drives_v, OpType);
7425 }
7426
7427 return(n);
7428}
7429
7430int attribute_update(LDAP *ldap_handle, char *distinguished_name,
7431 char *attribute_value, char *attribute, char *user_name)
7432{
7433 char *mod_v[] = {NULL, NULL};
7434 LDAPMod *DelMods[20];
7435 LDAPMod *mods[20];
7436 int n;
7437 int i;
7438 int rc;
7439
7440 if (strlen(attribute_value) == 0)
7441 {
7442 i = 0;
7443 DEL_ATTR(attribute, LDAP_MOD_DELETE);
7444 DelMods[i] = NULL;
7445 rc = ldap_modify_s(ldap_handle, distinguished_name, DelMods);
7446 free(DelMods[0]);
7447 }
7448 else
7449 {
7450 n = 0;
7451 mod_v[0] = attribute_value;
7452 ADD_ATTR(attribute, mod_v, LDAP_MOD_REPLACE);
7453 mods[n] = NULL;
7454
7455 if ((rc = ldap_modify_s(ldap_handle, distinguished_name,
7456 mods)) != LDAP_SUCCESS)
7457 {
7458 free(mods[0]);
7459 n = 0;
7460 mod_v[0] = attribute_value;
7461 ADD_ATTR(attribute, mod_v, LDAP_MOD_ADD);
7462 mods[n] = NULL;
7463
7464 if ((rc = ldap_modify_s(ldap_handle, distinguished_name,
7465 mods)) != LDAP_SUCCESS)
7466 {
7467 com_err(whoami, 0, "Unable to change the %s attribute for %s "
7468 "in the AD : %s",
7469 attribute, user_name, ldap_err2string(rc));
7470 }
7471 }
7472
7473 free(mods[0]);
7474 }
7475
7476 return(rc);
7477}
7478
7479void StringTrim(char *StringToTrim)
7480{
7481 char *t, *s;
7482 char *save;
7483
7484 save = strdup(StringToTrim);
7485
7486 s = save;
7487
7488 while (isspace(*s))
7489 s++;
7490
7491 /* skip to end of string */
7492 if (*s == '\0')
7493 {
7494 if (*save)
7495 *save = '\0';
7496 strcpy(StringToTrim, save);
7497 return;
7498 }
7499
7500 for (t = s; *t; t++)
7501 continue;
7502
7503 while (t > s)
7504 {
7505 --t;
7506 if (!isspace(*t))
7507 {
7508 t++;
7509 break;
7510 }
7511 }
7512
7513 if (*t)
7514 *t = '\0';
7515
7516 strcpy(StringToTrim, s);
7517 return;
7518}
7519
7520int ReadConfigFile(char *DomainName)
7521{
7522 int Count;
7523 int i;
7524 int k;
7525 char temp[256];
7526 char temp1[256];
7527 FILE *fptr;
7528
7529 Count = 0;
7530
7531 sprintf(temp, "%s%s.cfg", CFG_PATH, DomainName);
7532
7533 if ((fptr = fopen(temp, "r")) != NULL)
7534 {
7535 while (fgets(temp, sizeof(temp), fptr) != 0)
7536 {
7537 for (i = 0; i < (int)strlen(temp); i++)
7538 temp[i] = toupper(temp[i]);
7539
7540 if (temp[strlen(temp) - 1] == '\n')
7541 temp[strlen(temp) - 1] = '\0';
7542
7543 StringTrim(temp);
7544
7545 if (strlen(temp) == 0)
7546 continue;
7547
7548 if (!strncmp(temp, DOMAIN, strlen(DOMAIN)))
7549 {
7550 if (strlen(temp) > (strlen(DOMAIN)))
7551 {
7552 strcpy(ldap_domain, &temp[strlen(DOMAIN)]);
7553 StringTrim(ldap_domain);
7554 }
7555 }
7556 else if (!strncmp(temp, PRINCIPALNAME, strlen(PRINCIPALNAME)))
7557 {
7558 if (strlen(temp) > (strlen(PRINCIPALNAME)))
7559 {
7560 strcpy(PrincipalName, &temp[strlen(PRINCIPALNAME)]);
7561 StringTrim(PrincipalName);
7562 }
7563 }
7564 else if (!strncmp(temp, SERVER, strlen(SERVER)))
7565 {
7566 if (strlen(temp) > (strlen(SERVER)))
7567 {
7568 ServerList[Count] = calloc(1, 256);
7569 strcpy(ServerList[Count], &temp[strlen(SERVER)]);
7570 StringTrim(ServerList[Count]);
7571 ++Count;
7572 }
7573 }
7574 else if (!strncmp(temp, MSSFU, strlen(MSSFU)))
7575 {
7576 if (strlen(temp) > (strlen(MSSFU)))
7577 {
7578 strcpy(temp1, &temp[strlen(MSSFU)]);
7579 StringTrim(temp1);
7580 if (!strcmp(temp1, SFUTYPE))
7581 UseSFU30 = 1;
7582 }
7583 }
7584 else if (!strncmp(temp, GROUP_SUFFIX, strlen(GROUP_SUFFIX)))
7585 {
7586 if (strlen(temp) > (strlen(GROUP_SUFFIX)))
7587 {
7588 strcpy(temp1, &temp[strlen(GROUP_SUFFIX)]);
7589 StringTrim(temp1);
7590 if (!strcasecmp(temp1, "NO"))
7591 {
7592 UseGroupSuffix = 0;
7593 memset(group_suffix, '\0', sizeof(group_suffix));
7594 }
7595 }
7596 }
7597 else if (!strncmp(temp, GROUP_TYPE, strlen(GROUP_TYPE)))
7598 {
7599 if (strlen(temp) > (strlen(GROUP_TYPE)))
7600 {
7601 strcpy(temp1, &temp[strlen(GROUP_TYPE)]);
7602 StringTrim(temp1);
7603 if (!strcasecmp(temp1, "UNIVERSAL"))
7604 UseGroupUniversal = 1;
7605 }
7606 }
7607 else if (!strncmp(temp, SET_GROUP_ACE, strlen(SET_GROUP_ACE)))
7608 {
7609 if (strlen(temp) > (strlen(SET_GROUP_ACE)))
7610 {
7611 strcpy(temp1, &temp[strlen(SET_GROUP_ACE)]);
7612 StringTrim(temp1);
7613 if (!strcasecmp(temp1, "NO"))
7614 SetGroupAce = 0;
7615 }
7616 }
7617 else if (!strncmp(temp, SET_PASSWORD, strlen(SET_PASSWORD)))
7618 {
7619 if (strlen(temp) > (strlen(SET_PASSWORD)))
7620 {
7621 strcpy(temp1, &temp[strlen(SET_PASSWORD)]);
7622 StringTrim(temp1);
7623 if (!strcasecmp(temp1, "NO"))
7624 SetPassword = 0;
7625 }
7626 }
7627 else if (!strncmp(temp, EXCHANGE, strlen(EXCHANGE)))
7628 {
7629 if (strlen(temp) > (strlen(EXCHANGE)))
7630 {
7631 strcpy(temp1, &temp[strlen(EXCHANGE)]);
7632 StringTrim(temp1);
7633 if (!strcasecmp(temp1, "YES"))
7634 Exchange = 1;
7635 }
7636 }
7637 else if (!strncmp(temp, PROCESS_MACHINE_CONTAINER,
7638 strlen(PROCESS_MACHINE_CONTAINER)))
7639 {
7640 if (strlen(temp) > (strlen(PROCESS_MACHINE_CONTAINER)))
7641 {
7642 strcpy(temp1, &temp[strlen(PROCESS_MACHINE_CONTAINER)]);
7643 StringTrim(temp1);
7644 if (!strcasecmp(temp1, "NO"))
7645 ProcessMachineContainer = 0;
7646 }
7647 }
7648 else
7649 {
7650 if (strlen(ldap_domain) != 0)
7651 {
7652 memset(ldap_domain, '\0', sizeof(ldap_domain));
7653 break;
7654 }
7655
7656 if (strlen(temp) != 0)
7657 strcpy(ldap_domain, temp);
7658 }
7659 }
7660 fclose(fptr);
7661 }
7662
7663 if (strlen(ldap_domain) == 0)
7664 {
7665 strcpy(ldap_domain, DomainName);
7666 }
7667
7668 if (Count == 0)
7669 return(0);
7670
7671 for (i = 0; i < Count; i++)
7672 {
7673 if (ServerList[i] != 0)
7674 {
7675 strcat(ServerList[i], ".");
7676 strcat(ServerList[i], ldap_domain);
7677 for (k = 0; k < (int)strlen(ServerList[i]); k++)
7678 ServerList[i][k] = toupper(ServerList[i][k]);
7679 }
7680 }
7681
7682 return(0);
7683}
7684
7685int ReadDomainList()
7686{
7687 int Count;
7688 int i;
7689 char temp[128];
7690 char temp1[128];
7691 FILE *fptr;
7692 unsigned char c[11];
7693 unsigned char stuff[256];
7694 int rc;
7695 int ok;
7696
7697 Count = 0;
7698 sprintf(temp, "%s%s", CFG_PATH, WINADCFG);
7699
7700 if ((fptr = fopen(temp, "r")) != NULL)
7701 {
7702 while (fgets(temp, sizeof(temp), fptr) != 0)
7703 {
7704 for (i = 0; i < (int)strlen(temp); i++)
7705 temp[i] = toupper(temp[i]);
7706
7707 if (temp[strlen(temp) - 1] == '\n')
7708 temp[strlen(temp) - 1] = '\0';
7709
7710 StringTrim(temp);
7711
7712 if (strlen(temp) == 0)
7713 continue;
7714
7715 if (!strncmp(temp, DOMAIN, strlen(DOMAIN)))
7716 {
7717 if (strlen(temp) > (strlen(DOMAIN)))
7718 {
7719 strcpy(temp1, &temp[strlen(DOMAIN)]);
7720 StringTrim(temp1);
7721 strcpy(temp, temp1);
7722 }
7723 }
7724
7725 strcpy(DomainNames[Count], temp);
7726 StringTrim(DomainNames[Count]);
7727 ++Count;
7728 }
7729
7730 fclose(fptr);
7731 }
7732
7733 if (Count == 0)
7734 {
7735 critical_alert("incremental", "%s", "winad.incr cannot run due to a "
7736 "configuration error in winad.cfg");
7737 return(1);
7738 }
7739
7740 return(0);
7741}
7742
7743int email_isvalid(const char *address) {
7744 int count = 0;
7745 const char *c, *domain;
7746 static char *rfc822_specials = "()<>@,;:\\\"[]";
7747
7748 if(address[strlen(address) - 1] == '.')
7749 return 0;
7750
7751 /* first we validate the name portion (name@domain) */
7752 for (c = address; *c; c++) {
7753 if (*c == '\"' && (c == address || *(c - 1) == '.' || *(c - 1) ==
7754 '\"')) {
7755 while (*++c) {
7756 if (*c == '\"')
7757 break;
7758 if (*c == '\\' && (*++c == ' '))
7759 continue;
7760 if (*c <= ' ' || *c >= 127)
7761 return 0;
7762 }
7763
7764 if (!*c++)
7765 return 0;
7766 if (*c == '@')
7767 break;
7768 if (*c != '.')
7769 return 0;
7770 continue;
7771 }
7772
7773 if (*c == '@')
7774 break;
7775 if (*c <= ' ' || *c >= 127)
7776 return 0;
7777 if (strchr(rfc822_specials, *c))
7778 return 0;
7779 }
7780
7781 if (c == address || *(c - 1) == '.')
7782 return 0;
7783
7784 /* next we validate the domain portion (name@domain) */
7785 if (!*(domain = ++c)) return 0;
7786 do {
7787 if (*c == '.') {
7788 if (c == domain || *(c - 1) == '.')
7789 return 0;
7790 count++;
7791 }
7792 if (*c <= ' ' || *c >= 127)
7793 return 0;
7794 if (strchr(rfc822_specials, *c))
7795 return 0;
7796 } while (*++c);
7797
7798 return (count >= 1);
7799}
7800
7801int find_homeMDB(LDAP *ldap_handle, char *dn_path, char **homeMDB,
7802 char **homeServerName)
7803{
7804 LK_ENTRY *group_base;
7805 LK_ENTRY *sub_group_base;
7806 LK_ENTRY *gPtr;
7807 LK_ENTRY *sub_gPtr;
7808 int group_count;
7809 int sub_group_count;
7810 char filter[1024];
7811 char sub_filter[1024];
7812 char search_path[1024];
7813 char range[1024];
7814 char *attr_array[3];
7815 char *s;
7816 int homeMDB_count = -1;
7817 int rc;
7818 int i;
7819 int mdbbl_count;
7820 int rangeStep = 1500;
7821 int rangeLow = 0;
7822 int rangeHigh = rangeLow + (rangeStep - 1);
7823 int isLast = 0;
7824
7825 /* Grumble..... microsoft not making it searchable from the root *grr* */
7826
7827 memset(filter, '\0', sizeof(filter));
7828 memset(search_path, '\0', sizeof(search_path));
7829
7830 sprintf(filter, "(objectClass=msExchMDB)");
7831 sprintf(search_path, "CN=Configuration,%s", dn_path);
7832 attr_array[0] = "distinguishedName";
7833 attr_array[1] = NULL;
7834
7835 group_base = NULL;
7836 group_count = 0;
7837
7838 if ((rc = linklist_build(ldap_handle, search_path, filter, attr_array,
7839 &group_base, &group_count,
7840 LDAP_SCOPE_SUBTREE)) != 0)
7841 {
7842 com_err(whoami, 0, "Unable to find msExchMDB %s",
7843 ldap_err2string(rc));
7844 return(rc);
7845 }
7846
7847 if (group_count)
7848 {
7849 gPtr = group_base;
7850
7851 while(gPtr) {
7852 if (((s = strstr(gPtr->dn, "Public")) != (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.178538 seconds and 5 git commands to generate.