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