]> andersk Git - moira.git/blame - incremental/ldap/winad.c
Complain on mismatched usernames.
[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
6043 if(!strcasecmp(ptr->type, "USER"))
6044 {
6045 if ((rc = check_user(ldap_handle, dn_path, ptr->member,
6046 "")) == AD_NO_USER_FOUND)
6047 {
6048 com_err(whoami, 0, "creating user %s", ptr->member);
6049
6050 av[0] = ptr->member;
6051 call_args[0] = (char *)ldap_handle;
6052 call_args[1] = dn_path;
6053 call_args[2] = "";
6054 call_args[3] = NULL;
6055 callback_rc = 0;
6056
6057 if (rc = mr_query("get_user_account_by_login", 1, av,
6058 save_query_info, save_argv))
6059 {
6060 com_err(whoami, 0, "Unable to create user %s "
6061 "while populating group %s.", ptr->member,
6062 group_name);
6063
6064 return(3);
6065 }
6066
6067 if (rc = user_create(U_END, save_argv, call_args))
6068 {
6069 com_err(whoami, 0, "Unable to create user %s "
6070 "while populating group %s.", ptr->member,
6071 group_name);
6072
6073 return(3);
6074 }
6075
6076 if (callback_rc)
6077 {
6078 com_err(whoami, 0, "Unable to create user %s "
6079 "while populating group %s", ptr->member,
6080 group_name);
6081
6082 return(3);
6083 }
6084 }
6085
6086 pUserOu = user_ou;
6087
6088 if(ActiveDirectory)
6089 {
6090 sprintf(member, "cn=%s,%s,%s", ptr->member, pUserOu,
6091 dn_path);
6092 }
6093 else
6094 {
6095 sprintf(member, "uid=%s,%s,%s", ptr->member, pUserOu,
6096 dn_path);
6097 }
6098
6099 }
6100 else if (!strcasecmp(ptr->type, "STRING"))
6101 {
6102 if (contact_create(ldap_handle, dn_path, ptr->member,
6103 contact_ou))
6104 return(3);
6105
6106 pUserOu = contact_ou;
6107 sprintf(member, "cn=%s,%s,%s", escape_string(ptr->member),
6108 pUserOu, dn_path);
6109 }
6110 else if (!strcasecmp(ptr->type, "KERBEROS"))
6111 {
6112 if (contact_create(ldap_handle, dn_path, ptr->member,
6113 kerberos_ou))
6114 return(3);
6115
6116 pUserOu = kerberos_ou;
6117 sprintf(member, "cn=%s,%s,%s", escape_string(ptr->member),
6118 pUserOu, dn_path);
6119 }
6120
6121 if(i > 1)
6122 members = (char **)realloc(members, ((i + 2) * sizeof(char *)));
6123 members[i++] = strdup(member);
6124
6125 ptr = ptr->next;
6126 }
6127
6128 linklist_free(member_base);
6129 member_base = NULL;
6130 }
6131
6132 members[i] = NULL;
6133
6134 n = 0;
6135 ADD_ATTR("member", members, LDAP_MOD_REPLACE);
6136 mods[n] = NULL;
6137
6138 sprintf(group_dn, "cn=%s,%s,%s", group_name, group_ou, dn_path);
6139
6140 if ((rc = ldap_modify_s(ldap_handle, group_dn,
6141 mods)) != LDAP_SUCCESS)
6142 {
6143 com_err(whoami, 0,
6144 "Unable to populate group membership for %s: %s",
6145 group_dn, ldap_err2string(rc));
6146 }
6147
6148 for (i = 0; i < n; i++)
6149 free(mods[i]);
6150
6151 free(members);
6152
6153 return(0);
6154}
6155
6156int process_group(LDAP *ldap_handle, char *dn_path, char *MoiraId,
6157 char *group_name, char *group_ou, char *group_membership,
6158 int group_security_flag, int type, char *maillist)
6159{
6160 char before_desc[512];
6161 char before_name[256];
6162 char before_group_ou[256];
6163 char before_group_membership[2];
6164 char distinguishedName[256];
6165 char ad_distinguishedName[256];
6166 char filter[128];
6167 char *attr_array[3];
6168 int before_security_flag;
6169 int group_count;
6170 int rc;
6171 LK_ENTRY *group_base;
6172 LK_ENTRY *ptr;
6173 char ou_both[512];
6174 char ou_security[512];
6175 char ou_distribution[512];
6176 char ou_neither[512];
6177 char group_dn[512];
6178
6179 memset(ad_distinguishedName, '\0', sizeof(ad_distinguishedName));
6180 sprintf(distinguishedName, "CN=%s,%s,%s", group_name, group_ou, dn_path);
6181
6182 memset(filter, '\0', sizeof(filter));
6183 group_base = NULL;
6184 group_count = 0;
6185
6186 if (rc = ad_get_group(ldap_handle, dn_path, group_name,
6187 "*", MoiraId,
6188 "samAccountName", &group_base,
6189 &group_count, filter))
6190 return(rc);
6191
6192 if (type == CHECK_GROUPS)
6193 {
6194 if (group_count == 1)
6195 {
6196 strcpy(group_dn, group_base->dn);
6197
6198 if (!strcasecmp(group_dn, distinguishedName))
6199 {
6200 linklist_free(group_base);
6201 return(0);
6202 }
6203 }
6204
6205 linklist_free(group_base);
6206
6207 if (group_count == 0)
6208 return(AD_NO_GROUPS_FOUND);
6209
6210 if (group_count == 1)
6211 return(AD_WRONG_GROUP_DN_FOUND);
6212
6213 return(AD_MULTIPLE_GROUPS_FOUND);
6214 }
6215
6216 if (group_count == 0)
6217 {
6218 return(AD_NO_GROUPS_FOUND);
6219 }
6220
6221 if (group_count > 1)
6222 {
6223 ptr = group_base;
6224
6225 strcpy(group_dn, ptr->dn);
6226
6227 while (ptr != NULL)
6228 {
6229 if (!strcasecmp(group_dn, ptr->value))
6230 break;
6231
6232 ptr = ptr->next;
6233 }
6234
6235 if (ptr == NULL)
6236 {
6237 com_err(whoami, 0, "%d groups with moira id = %s", group_count,
6238 MoiraId);
6239 ptr = group_base;
6240
6241 while (ptr != NULL)
6242 {
6243 com_err(whoami, 0, "%s with moira id = %s", ptr->value, MoiraId);
6244 ptr = ptr->next;
6245 }
6246
6247 linklist_free(group_base);
6248 return(AD_MULTIPLE_GROUPS_FOUND);
6249 }
6250
6251 ptr = group_base;
6252
6253 while (ptr != NULL)
6254 {
6255 strcpy(group_dn, ptr->dn);
6256
6257 if (strcasecmp(group_dn, ptr->value))
6258 rc = ldap_delete_s(ldap_handle, ptr->value);
6259
6260 ptr = ptr->next;
6261 }
6262
6263 linklist_free(group_base);
6264 memset(filter, '\0', sizeof(filter));
6265 group_base = NULL;
6266 group_count = 0;
6267
6268 if (rc = ad_get_group(ldap_handle, dn_path, group_name,
6269 "*", MoiraId,
6270 "samAccountName", &group_base,
6271 &group_count, filter))
6272 return(rc);
6273
6274 if (group_count == 0)
6275 return(AD_NO_GROUPS_FOUND);
6276
6277 if (group_count > 1)
6278 return(AD_MULTIPLE_GROUPS_FOUND);
6279 }
6280
6281 strcpy(ad_distinguishedName, group_base->dn);
6282 linklist_free(group_base);
6283 group_base = NULL;
6284 group_count = 0;
6285
6286 attr_array[0] = "sAMAccountName";
6287 attr_array[1] = NULL;
6288
6289 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6290 &group_base, &group_count,
6291 LDAP_SCOPE_SUBTREE)) != 0)
6292 {
6293 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
6294 MoiraId, ldap_err2string(rc));
6295 return(rc);
6296 }
6297
6298 sprintf(filter, "(sAMAccountName=%s)", group_base->value);
6299
6300 if (!strcasecmp(ad_distinguishedName, distinguishedName))
6301 {
6302 linklist_free(group_base);
6303 group_base = NULL;
6304 group_count = 0;
6305 return(0);
6306 }
6307
6308 linklist_free(group_base);
6309 group_base = NULL;
6310 group_count = 0;
6311 memset(ou_both, '\0', sizeof(ou_both));
6312 memset(ou_security, '\0', sizeof(ou_security));
6313 memset(ou_distribution, '\0', sizeof(ou_distribution));
6314 memset(ou_neither, '\0', sizeof(ou_neither));
6315 memset(before_name, '\0', sizeof(before_name));
6316 memset(before_desc, '\0', sizeof(before_desc));
6317 memset(before_group_membership, '\0', sizeof(before_group_membership));
6318
6319 attr_array[0] = "name";
6320 attr_array[1] = NULL;
6321
6322 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6323 &group_base, &group_count,
6324 LDAP_SCOPE_SUBTREE)) != 0)
6325 {
6326 com_err(whoami, 0, "Unable to get list name with MoiraId = %s: %s",
6327 MoiraId, ldap_err2string(rc));
6328 return(rc);
6329 }
6330
6331 strcpy(before_name, group_base->value);
6332 linklist_free(group_base);
6333 group_base = NULL;
6334 group_count = 0;
6335
6336 attr_array[0] = "description";
6337 attr_array[1] = NULL;
6338
6339 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6340 &group_base, &group_count,
6341 LDAP_SCOPE_SUBTREE)) != 0)
6342 {
6343 com_err(whoami, 0,
6344 "Unable to get list description with MoiraId = %s: %s",
6345 MoiraId, ldap_err2string(rc));
6346 return(rc);
6347 }
6348
6349 if (group_count != 0)
6350 {
6351 strcpy(before_desc, group_base->value);
6352 linklist_free(group_base);
6353 group_base = NULL;
6354 group_count = 0;
6355 }
6356
6357 change_to_lower_case(ad_distinguishedName);
6358 strcpy(ou_both, group_ou_both);
6359 change_to_lower_case(ou_both);
6360 strcpy(ou_security, group_ou_security);
6361 change_to_lower_case(ou_security);
6362 strcpy(ou_distribution, group_ou_distribution);
6363 change_to_lower_case(ou_distribution);
6364 strcpy(ou_neither, group_ou_neither);
6365 change_to_lower_case(ou_neither);
6366
6367 if (strstr(ad_distinguishedName, ou_both))
6368 {
6369 strcpy(before_group_ou, group_ou_both);
6370 before_group_membership[0] = 'B';
6371 before_security_flag = 1;
6372 }
6373 else if (strstr(ad_distinguishedName, ou_security))
6374 {
6375 strcpy(before_group_ou, group_ou_security);
6376 before_group_membership[0] = 'S';
6377 before_security_flag = 1;
6378 }
6379 else if (strstr(ad_distinguishedName, ou_distribution))
6380 {
6381 strcpy(before_group_ou, group_ou_distribution);
6382 before_group_membership[0] = 'D';
6383 before_security_flag = 0;
6384 }
6385 else if (strstr(ad_distinguishedName, ou_neither))
6386 {
6387 strcpy(before_group_ou, group_ou_neither);
6388 before_group_membership[0] = 'N';
6389 before_security_flag = 0;
6390 }
6391 else
6392 return(AD_NO_OU_FOUND);
6393
6394 rc = group_rename(ldap_handle, dn_path, before_name,
6395 before_group_membership,
6396 before_group_ou, before_security_flag, before_desc,
6397 group_name, group_membership, group_ou,
6398 group_security_flag,
6399 before_desc, MoiraId, filter, maillist);
6400
6401 return(rc);
6402}
6403
6404void change_to_lower_case(char *ptr)
6405{
6406 int i;
6407
6408 for (i = 0; i < (int)strlen(ptr); i++)
6409 {
6410 ptr[i] = tolower(ptr[i]);
6411 }
6412}
6413
6414int ad_get_group(LDAP *ldap_handle, char *dn_path,
6415 char *group_name, char *group_membership,
6416 char *MoiraId, char *attribute,
6417 LK_ENTRY **linklist_base, int *linklist_count,
6418 char *rFilter)
6419{
6420 LK_ENTRY *pPtr;
6421 char filter[128];
6422 char *attr_array[3];
6423 char *dn;
6424 int rc;
6425
6426 (*linklist_base) = NULL;
6427 (*linklist_count) = 0;
6428
6429 if (strlen(rFilter) != 0)
6430 {
6431 strcpy(filter, rFilter);
6432 attr_array[0] = attribute;
6433 attr_array[1] = NULL;
6434
6435 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6436 linklist_base, linklist_count,
6437 LDAP_SCOPE_SUBTREE)) != 0)
6438 {
6439 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
6440 MoiraId, ldap_err2string(rc));
6441 return(rc);
6442 }
6443
6444 if ((*linklist_count) == 1)
6445 {
6446 strcpy(rFilter, filter);
6447 return(0);
6448 }
6449 }
6450
6451 linklist_free((*linklist_base));
6452 (*linklist_base) = NULL;
6453 (*linklist_count) = 0;
6454
6455 if (strlen(MoiraId) != 0)
6456 {
6457 sprintf(filter, "(&(objectClass=group)(mitMoiraId=%s))", MoiraId);
6458
6459 attr_array[0] = attribute;
6460 attr_array[1] = NULL;
6461
6462 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6463 linklist_base, linklist_count,
6464 LDAP_SCOPE_SUBTREE)) != 0)
6465 {
6466 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
6467 MoiraId, ldap_err2string(rc));
6468 return(rc);
6469 }
6470 }
6471
6472 if ((*linklist_count) > 1)
6473 {
6474 com_err(whoami, 0, "multiple groups with mitMoiraId = %s", MoiraId);
6475 pPtr = (*linklist_base);
6476
6477 while (pPtr)
6478 {
6479 com_err(whoami, 0, "groups %s has mitMoiraId = %s", pPtr->value,
6480 MoiraId);
6481 pPtr = pPtr->next;
6482 }
6483
6484 linklist_free((*linklist_base));
6485 (*linklist_base) = NULL;
6486 (*linklist_count) = 0;
6487 }
6488
6489 if ((*linklist_count) == 1)
6490 {
6491
6492 pPtr = (*linklist_base);
6493 dn = strdup(pPtr->dn);
6494 dn += 3;
6495
6496 if (!memcmp(dn, group_name, strlen(group_name)))
6497 {
6498 strcpy(rFilter, filter);
6499 return(0);
6500 }
6501 }
6502
6503 linklist_free((*linklist_base));
6504 (*linklist_base) = NULL;
6505 (*linklist_count) = 0;
6506 sprintf(filter, "(sAMAccountName=%s%s)", group_name, group_suffix);
6507
6508 attr_array[0] = attribute;
6509 attr_array[1] = NULL;
6510
6511 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6512 linklist_base, linklist_count,
6513 LDAP_SCOPE_SUBTREE)) != 0)
6514 {
6515 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
6516 MoiraId, ldap_err2string(rc));
6517 return(rc);
6518 }
6519
6520 if ((*linklist_count) == 1)
6521 {
6522 strcpy(rFilter, filter);
6523 return(0);
6524 }
6525
6526 return(0);
6527}
6528
6529int check_user(LDAP *ldap_handle, char *dn_path, char *UserName, char *MoiraId)
6530{
6531 char filter[128];
6532 char *attr_array[3];
6533 char SamAccountName[64];
6534 int group_count;
6535 int rc;
6536 LK_ENTRY *group_base;
6537 LK_ENTRY *gPtr;
6538
6539 group_count = 0;
6540 group_base = NULL;
6541
6542 if (strlen(MoiraId) != 0)
6543 {
6544 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
6545
6546 attr_array[0] = "sAMAccountName";
6547 attr_array[1] = NULL;
6548 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6549 &group_base, &group_count,
6550 LDAP_SCOPE_SUBTREE)) != 0)
6551 {
6552 com_err(whoami, 0, "Unable to process user %s : %s",
6553 UserName, ldap_err2string(rc));
6554 return(rc);
6555 }
6556
6557 if (group_count > 1)
6558 {
6559 com_err(whoami, 0, "multiple users exist with MoiraId = %s",
6560 MoiraId);
6561 gPtr = group_base;
6562
6563 while (gPtr)
6564 {
6565 com_err(whoami, 0, "user %s exist with MoiraId = %s",
6566 gPtr->value, MoiraId);
6567 gPtr = gPtr->next;
6568 }
6569 }
6570 }
6571
6572 if (group_count != 1)
6573 {
6574 linklist_free(group_base);
6575 group_count = 0;
6576 group_base = NULL;
6577 sprintf(filter, "(sAMAccountName=%s)", UserName);
6578 attr_array[0] = "sAMAccountName";
6579 attr_array[1] = NULL;
6580
6581 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6582 &group_base, &group_count,
6583 LDAP_SCOPE_SUBTREE)) != 0)
6584 {
6585 com_err(whoami, 0, "Unable to process user %s : %s",
6586 UserName, ldap_err2string(rc));
6587 return(rc);
6588 }
6589 }
6590
6591 if (group_count != 1)
6592 {
6593 linklist_free(group_base);
6594 return(AD_NO_USER_FOUND);
6595 }
6596
6597 strcpy(SamAccountName, group_base->value);
6598 linklist_free(group_base);
6599 group_count = 0;
6600 rc = 0;
6601
6602 if (strcmp(SamAccountName, UserName))
6603 {
a20c63cf 6604 com_err(whoami, 0,
6605 "User object %s with MoiraId %s has mismatched usernames "
6606 "(LDAP username %s, Moira username %s)", SamAccountName,
6607 MoiraId, SamAccountName, UserName);
61a2844b 6608 }
6609
6610 return(0);
6611}
6612
6613void container_get_dn(char *src, char *dest)
6614{
6615 char *sPtr;
6616 char *array[20];
6617 char name[256];
6618 int n;
6619
6620 memset(array, '\0', 20 * sizeof(array[0]));
6621
6622 if (strlen(src) == 0)
6623 return;
6624
6625 strcpy(name, src);
6626 sPtr = name;
6627 n = 0;
6628 array[n] = name;
6629 ++n;
6630
6631 while (*sPtr)
6632 {
6633 if ((*sPtr) == '/')
6634 {
6635 (*sPtr) = '\0';
6636 ++sPtr;
6637 array[n] = sPtr;
6638 ++n;
6639 }
6640 else
6641 ++sPtr;
6642 }
6643
6644 strcpy(dest, "OU=");
6645
6646 while (n != 0)
6647 {
6648 strcat(dest, array[n-1]);
6649 --n;
6650 if (n > 0)
6651 {
6652 strcat(dest, ",OU=");
6653 }
6654 }
6655
6656 return;
6657}
6658
6659void container_get_name(char *src, char *dest)
6660{
6661 char *sPtr;
6662 char *dPtr;
6663
6664 if (strlen(src) == 0)
6665 return;
6666
6667 sPtr = src;
6668 dPtr = src;
6669
6670 while (*sPtr)
6671 {
6672 if ((*sPtr) == '/')
6673 {
6674 dPtr = sPtr;
6675 ++dPtr;
6676 }
6677 ++sPtr;
6678 }
6679
6680 strcpy(dest, dPtr);
6681 return;
6682}
6683
6684void container_check(LDAP *ldap_handle, char *dn_path, char *name)
6685{
6686 char cName[256];
6687 char *av[7];
6688 int i;
6689 int rc;
6690
6691 strcpy(cName, name);
6692
6693 for (i = 0; i < (int)strlen(cName); i++)
6694 {
6695 if (cName[i] == '/')
6696 {
6697 cName[i] = '\0';
6698 av[CONTAINER_NAME] = cName;
6699 av[CONTAINER_DESC] = "";
6700 av[CONTAINER_LOCATION] = "";
6701 av[CONTAINER_CONTACT] = "";
6702 av[CONTAINER_TYPE] = "";
6703 av[CONTAINER_ID] = "";
6704 av[CONTAINER_ROWID] = "";
6705 rc = container_create(ldap_handle, dn_path, 7, av);
6706
6707 if (rc == LDAP_SUCCESS)
6708 {
6709 com_err(whoami, 0, "container %s created without a mitMoiraId",
6710 cName);
6711 }
6712
6713 cName[i] = '/';
6714 }
6715 }
6716}
6717
6718int container_rename(LDAP *ldap_handle, char *dn_path, int beforec,
6719 char **before, int afterc, char **after)
6720{
6721 char dName[256];
6722 char cName[256];
6723 char new_cn[128];
6724 char new_dn_path[256];
6725 char temp[256];
6726 char distinguishedName[256];
6727 char *pPtr;
6728 int rc;
6729 int i;
6730
6731 memset(cName, '\0', sizeof(cName));
6732 container_get_name(after[CONTAINER_NAME], cName);
6733
6734 if (!check_container_name(cName))
6735 {
6736 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
6737 cName);
6738 return(AD_INVALID_NAME);
6739 }
6740
6741 memset(distinguishedName, '\0', sizeof(distinguishedName));
6742
6743 if (rc = container_get_distinguishedName(ldap_handle, dn_path,
6744 distinguishedName, beforec, before))
6745 return(rc);
6746
6747 if (strlen(distinguishedName) == 0)
6748 {
6749 rc = container_create(ldap_handle, dn_path, afterc, after);
6750 return(rc);
6751 }
6752
6753 strcpy(temp, after[CONTAINER_NAME]);
6754 pPtr = temp;
6755
6756 for (i = 0; i < (int)strlen(temp); i++)
6757 {
6758 if (temp[i] == '/')
6759 {
6760 pPtr = &temp[i];
6761 }
6762 }
6763
6764 (*pPtr) = '\0';
6765
6766 container_get_dn(temp, dName);
6767
6768 if (strlen(temp) != 0)
6769 sprintf(new_dn_path, "%s,%s", dName, dn_path);
6770 else
6771 sprintf(new_dn_path, "%s", dn_path);
6772
6773 sprintf(new_cn, "OU=%s", cName);
6774
6775 container_check(ldap_handle, dn_path, after[CONTAINER_NAME]);
6776
6777 if ((rc = ldap_rename_s(ldap_handle, distinguishedName, new_cn, new_dn_path,
6778 TRUE, NULL, NULL)) != LDAP_SUCCESS)
6779 {
6780 com_err(whoami, 0, "Unable to rename container from %s to %s : %s",
6781 before[CONTAINER_NAME], after[CONTAINER_NAME],
6782 ldap_err2string(rc));
6783 return(rc);
6784 }
6785
6786 memset(dName, '\0', sizeof(dName));
6787 container_get_dn(after[CONTAINER_NAME], dName);
6788 rc = container_adupdate(ldap_handle, dn_path, dName, "", afterc, after);
6789
6790 return(rc);
6791}
6792
6793int container_delete(LDAP *ldap_handle, char *dn_path, int count, char **av)
6794{
6795 char distinguishedName[256];
6796 int rc;
6797
6798 memset(distinguishedName, '\0', sizeof(distinguishedName));
6799
6800 if (rc = container_get_distinguishedName(ldap_handle, dn_path,
6801 distinguishedName, count, av))
6802 return(rc);
6803
6804 if (strlen(distinguishedName) == 0)
6805 return(0);
6806
6807 if ((rc = ldap_delete_s(ldap_handle, distinguishedName)) != LDAP_SUCCESS)
6808 {
6809 if (rc == LDAP_NOT_ALLOWED_ON_NONLEAF)
6810 container_move_objects(ldap_handle, dn_path, distinguishedName);
6811 else
6812 com_err(whoami, 0, "Unable to delete container %s from AD : %s",
6813 av[CONTAINER_NAME], ldap_err2string(rc));
6814 }
6815
6816 return(rc);
6817}
6818
6819int container_create(LDAP *ldap_handle, char *dn_path, int count, char **av)
6820{
6821 char *attr_array[3];
6822 LK_ENTRY *group_base;
6823 int group_count;
6824 LDAPMod *mods[20];
6825 char *objectClass_v[] = {"top",
6826 "organizationalUnit",
6827 NULL};
6828
6829 char *ou_v[] = {NULL, NULL};
6830 char *name_v[] = {NULL, NULL};
6831 char *moiraId_v[] = {NULL, NULL};
6832 char *desc_v[] = {NULL, NULL};
6833 char *managedBy_v[] = {NULL, NULL};
6834 char dName[256];
6835 char cName[256];
6836 char managedByDN[256];
6837 char filter[256];
6838 char temp[256];
6839 int n;
6840 int i;
6841 int rc;
6842
6843 memset(filter, '\0', sizeof(filter));
6844 memset(dName, '\0', sizeof(dName));
6845 memset(cName, '\0', sizeof(cName));
6846 memset(managedByDN, '\0', sizeof(managedByDN));
6847 container_get_dn(av[CONTAINER_NAME], dName);
6848 container_get_name(av[CONTAINER_NAME], cName);
6849
6850 if ((strlen(cName) == 0) || (strlen(dName) == 0))
6851 {
6852 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
6853 cName);
6854 return(AD_INVALID_NAME);
6855 }
6856
6857 if (!check_container_name(cName))
6858 {
6859 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
6860 cName);
6861 return(AD_INVALID_NAME);
6862 }
6863
6864 n = 0;
6865 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
6866 name_v[0] = cName;
6867 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
6868 ou_v[0] = cName;
6869 ADD_ATTR("ou", ou_v, LDAP_MOD_ADD);
6870
6871 if (strlen(av[CONTAINER_ROWID]) != 0)
6872 {
6873 moiraId_v[0] = av[CONTAINER_ROWID];
6874 ADD_ATTR("mitMoiraId", moiraId_v, LDAP_MOD_ADD);
6875 }
6876
6877 if (strlen(av[CONTAINER_DESC]) != 0)
6878 {
6879 desc_v[0] = av[CONTAINER_DESC];
6880 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
6881 }
6882
6883 if ((strlen(av[CONTAINER_TYPE]) != 0) && (strlen(av[CONTAINER_ID]) != 0))
6884 {
6885 if (!strcasecmp(av[CONTAINER_TYPE], "KERBEROS"))
6886 {
6887 if (!contact_create(ldap_handle, dn_path, av[CONTAINER_ID],
6888 kerberos_ou))
6889 {
6890 sprintf(managedByDN, "CN=%s,%s,%s", av[CONTAINER_ID],
6891 kerberos_ou, dn_path);
6892 managedBy_v[0] = managedByDN;
6893 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_ADD);
6894 }
6895 }
6896 else
6897 {
6898 if (!strcasecmp(av[CONTAINER_TYPE], "USER"))
6899 {
6900 sprintf(filter, "(&(cn=%s)(&(objectCategory=person)"
6901 "(objectClass=user)))", av[CONTAINER_ID]);
6902 }
6903
6904 if (!strcasecmp(av[CONTAINER_TYPE], "LIST"))
6905 {
6906 sprintf(filter, "(&(objectClass=group)(cn=%s))",
6907 av[CONTAINER_ID]);
6908 }
6909
6910 if (strlen(filter) != 0)
6911 {
6912 attr_array[0] = "distinguishedName";
6913 attr_array[1] = NULL;
6914 group_count = 0;
6915 group_base = NULL;
6916 if ((rc = linklist_build(ldap_handle, dn_path, filter,
6917 attr_array,
6918 &group_base, &group_count,
6919 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
6920 {
6921 if (group_count == 1)
6922 {
6923 strcpy(managedByDN, group_base->value);
6924 managedBy_v[0] = managedByDN;
6925 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_ADD);
6926 }
6927 linklist_free(group_base);
6928 group_base = NULL;
6929 group_count = 0;
6930 }
6931 }
6932 }
6933 }
6934
6935 mods[n] = NULL;
6936
6937 sprintf(temp, "%s,%s", dName, dn_path);
6938 rc = ldap_add_ext_s(ldap_handle, temp, mods, NULL, NULL);
6939
6940 for (i = 0; i < n; i++)
6941 free(mods[i]);
6942
6943 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
6944 {
6945 com_err(whoami, 0, "Unable to create container %s : %s",
6946 cName, ldap_err2string(rc));
6947 return(rc);
6948 }
6949
6950 if (rc == LDAP_ALREADY_EXISTS)
6951 {
6952 if (strlen(av[CONTAINER_ROWID]) != 0)
6953 rc = container_adupdate(ldap_handle, dn_path, dName, "", count, av);
6954 }
6955
6956 return(rc);
6957}
6958
6959int container_update(LDAP *ldap_handle, char *dn_path, int beforec,
6960 char **before, int afterc, char **after)
6961{
6962 char distinguishedName[256];
6963 int rc;
6964
6965 memset(distinguishedName, '\0', sizeof(distinguishedName));
6966
6967 if (rc = container_get_distinguishedName(ldap_handle, dn_path,
6968 distinguishedName, afterc, after))
6969 return(rc);
6970
6971 if (strlen(distinguishedName) == 0)
6972 {
6973 rc = container_create(ldap_handle, dn_path, afterc, after);
6974 return(rc);
6975 }
6976
6977 container_check(ldap_handle, dn_path, after[CONTAINER_NAME]);
6978 rc = container_adupdate(ldap_handle, dn_path, "", distinguishedName, afterc,
6979 after);
6980
6981 return(rc);
6982}
6983
6984int container_get_distinguishedName(LDAP *ldap_handle, char *dn_path,
6985 char *distinguishedName, int count,
6986 char **av)
6987{
6988 char *attr_array[3];
6989 LK_ENTRY *group_base;
6990 int group_count;
6991 char dName[256];
6992 char cName[256];
6993 char filter[512];
6994 int rc;
6995
6996 memset(filter, '\0', sizeof(filter));
6997 memset(dName, '\0', sizeof(dName));
6998 memset(cName, '\0', sizeof(cName));
6999 container_get_dn(av[CONTAINER_NAME], dName);
7000 container_get_name(av[CONTAINER_NAME], cName);
7001
7002 if (strlen(dName) == 0)
7003 {
7004 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
7005 av[CONTAINER_NAME]);
7006 return(AD_INVALID_NAME);
7007 }
7008
7009 if (!check_container_name(cName))
7010 {
7011 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
7012 cName);
7013 return(AD_INVALID_NAME);
7014 }
7015
7016 sprintf(filter, "(&(objectClass=organizationalUnit)(mitMoiraId=%s))",
7017 av[CONTAINER_ROWID]);
7018 attr_array[0] = "distinguishedName";
7019 attr_array[1] = NULL;
7020 group_count = 0;
7021 group_base = NULL;
7022
7023 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
7024 &group_base, &group_count,
7025 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
7026 {
7027 if (group_count == 1)
7028 {
7029 strcpy(distinguishedName, group_base->value);
7030 }
7031
7032 linklist_free(group_base);
7033 group_base = NULL;
7034 group_count = 0;
7035 }
7036
7037 if (strlen(distinguishedName) == 0)
7038 {
7039 sprintf(filter, "(&(objectClass=organizationalUnit)"
7040 "(distinguishedName=%s,%s))", dName, dn_path);
7041 attr_array[0] = "distinguishedName";
7042 attr_array[1] = NULL;
7043 group_count = 0;
7044 group_base = NULL;
7045
7046 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
7047 &group_base, &group_count,
7048 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
7049 {
7050 if (group_count == 1)
7051 {
7052 strcpy(distinguishedName, group_base->value);
7053 }
7054
7055 linklist_free(group_base);
7056 group_base = NULL;
7057 group_count = 0;
7058 }
7059 }
7060
7061 return(0);
7062}
7063
7064int container_adupdate(LDAP *ldap_handle, char *dn_path, char *dName,
7065 char *distinguishedName, int count, char **av)
7066{
7067 char *attr_array[5];
7068 LK_ENTRY *group_base;
7069 LK_ENTRY *pPtr;
7070 LDAPMod *mods[20];
7071 int group_count;
7072 char filter[512];
7073 char *moiraId_v[] = {NULL, NULL};
7074 char *desc_v[] = {NULL, NULL};
7075 char *managedBy_v[] = {NULL, NULL};
7076 char managedByDN[256];
7077 char moiraId[64];
7078 char desc[256];
7079 char ad_path[512];
7080 int rc;
7081 int i;
7082 int n;
7083
7084
7085 strcpy(ad_path, distinguishedName);
7086
7087 if (strlen(dName) != 0)
7088 sprintf(ad_path, "%s,%s", dName, dn_path);
7089
7090 sprintf(filter, "(&(objectClass=organizationalUnit)(distinguishedName=%s))",
7091 ad_path);
7092
7093 if (strlen(av[CONTAINER_ID]) != 0)
7094 sprintf(filter, "(&(objectClass=organizationalUnit)(mitMoiraId=%s))",
7095 av[CONTAINER_ROWID]);
7096
7097 attr_array[0] = "mitMoiraId";
7098 attr_array[1] = "description";
7099 attr_array[2] = "managedBy";
7100 attr_array[3] = NULL;
7101 group_count = 0;
7102 group_base = NULL;
7103
7104 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
7105 &group_base, &group_count,
7106 LDAP_SCOPE_SUBTREE)) != LDAP_SUCCESS)
7107 {
7108 com_err(whoami, 0, "Unable to retreive container info for %s : %s",
7109 av[CONTAINER_NAME], ldap_err2string(rc));
7110 return(rc);
7111 }
7112
7113 memset(managedByDN, '\0', sizeof(managedByDN));
7114 memset(moiraId, '\0', sizeof(moiraId));
7115 memset(desc, '\0', sizeof(desc));
7116 pPtr = group_base;
7117
7118 while (pPtr)
7119 {
7120 if (!strcasecmp(pPtr->attribute, "description"))
7121 strcpy(desc, pPtr->value);
7122 else if (!strcasecmp(pPtr->attribute, "managedBy"))
7123 strcpy(managedByDN, pPtr->value);
7124 else if (!strcasecmp(pPtr->attribute, "mitMoiraId"))
7125 strcpy(moiraId, pPtr->value);
7126 pPtr = pPtr->next;
7127 }
7128
7129 linklist_free(group_base);
7130 group_base = NULL;
7131 group_count = 0;
7132
7133 n = 0;
7134 if (strlen(av[CONTAINER_ROWID]) != 0)
7135 {
7136 moiraId_v[0] = av[CONTAINER_ROWID];
7137 ADD_ATTR("mitMoiraId", moiraId_v, LDAP_MOD_REPLACE);
7138 }
7139
7140 if (strlen(av[CONTAINER_DESC]) != 0)
7141 {
7142 attribute_update(ldap_handle, ad_path, av[CONTAINER_DESC], "description",
7143 dName);
7144 }
7145 else
7146 {
7147 if (strlen(desc) != 0)
7148 {
7149 attribute_update(ldap_handle, ad_path, "", "description", dName);
7150 }
7151 }
7152
7153 if ((strlen(av[CONTAINER_TYPE]) != 0) && (strlen(av[CONTAINER_ID]) != 0))
7154 {
7155 if (!strcasecmp(av[CONTAINER_TYPE], "KERBEROS"))
7156 {
7157 if (!contact_create(ldap_handle, dn_path, av[CONTAINER_ID],
7158 kerberos_ou))
7159 {
7160 sprintf(managedByDN, "CN=%s,%s,%s", av[CONTAINER_ID],
7161 kerberos_ou, dn_path);
7162 managedBy_v[0] = managedByDN;
7163 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_REPLACE);
7164 }
7165 else
7166 {
7167 if (strlen(managedByDN) != 0)
7168 {
7169 attribute_update(ldap_handle, ad_path, "", "managedBy",
7170 dName);
7171 }
7172 }
7173 }
7174 else
7175 {
7176 memset(filter, '\0', sizeof(filter));
7177
7178 if (!strcasecmp(av[CONTAINER_TYPE], "USER"))
7179 {
7180 sprintf(filter, "(&(cn=%s)(&(objectCategory=person)"
7181 "(objectClass=user)))", av[CONTAINER_ID]);
7182 }
7183
7184 if (!strcasecmp(av[CONTAINER_TYPE], "LIST"))
7185 {
7186 sprintf(filter, "(&(objectClass=group)(cn=%s))",
7187 av[CONTAINER_ID]);
7188 }
7189
7190 if (strlen(filter) != 0)
7191 {
7192 attr_array[0] = "distinguishedName";
7193 attr_array[1] = NULL;
7194 group_count = 0;
7195 group_base = NULL;
7196 if ((rc = linklist_build(ldap_handle, dn_path, filter,
7197 attr_array, &group_base, &group_count,
7198 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
7199 {
7200 if (group_count == 1)
7201 {
7202 strcpy(managedByDN, group_base->value);
7203 managedBy_v[0] = managedByDN;
7204 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_REPLACE);
7205 }
7206 else
7207 {
7208 if (strlen(managedByDN) != 0)
7209 {
7210 attribute_update(ldap_handle, ad_path, "",
7211 "managedBy", dName);
7212 }
7213 }
7214
7215 linklist_free(group_base);
7216 group_base = NULL;
7217 group_count = 0;
7218 }
7219 }
7220 else
7221 {
7222 if (strlen(managedByDN) != 0)
7223 {
7224 attribute_update(ldap_handle, ad_path, "", "managedBy",
7225 dName);
7226 }
7227 }
7228 }
7229 }
7230
7231 mods[n] = NULL;
7232
7233 if (n == 0)
7234 return(LDAP_SUCCESS);
7235
7236 rc = ldap_modify_s(ldap_handle, ad_path, mods);
7237
7238 for (i = 0; i < n; i++)
7239 free(mods[i]);
7240
7241 if (rc != LDAP_SUCCESS)
7242 {
7243 com_err(whoami, 0, "Unable to modify container info for %s : %s",
7244 av[CONTAINER_NAME], ldap_err2string(rc));
7245 return(rc);
7246 }
7247
7248 return(rc);
7249}
7250
7251int container_move_objects(LDAP *ldap_handle, char *dn_path, char *dName)
7252{
7253 char *attr_array[3];
7254 LK_ENTRY *group_base;
7255 LK_ENTRY *pPtr;
7256 int group_count;
7257 char filter[512];
7258 char new_cn[128];
7259 char temp[256];
7260 int rc;
7261 int NumberOfEntries = 10;
7262 int i;
7263 int count;
7264
7265 rc = ldap_set_option(ldap_handle, LDAP_OPT_SIZELIMIT, &NumberOfEntries);
7266
7267 for (i = 0; i < 3; i++)
7268 {
7269 memset(filter, '\0', sizeof(filter));
7270
7271 if (i == 0)
7272 {
7273 strcpy(filter, "(!(|(objectClass=computer)"
7274 "(objectClass=organizationalUnit)))");
7275 attr_array[0] = "cn";
7276 attr_array[1] = NULL;
7277 }
7278 else if (i == 1)
7279 {
7280 strcpy(filter, "(objectClass=computer)");
7281 attr_array[0] = "cn";
7282 attr_array[1] = NULL;
7283 }
7284 else
7285 {
7286 strcpy(filter, "(objectClass=organizationalUnit)");
7287 attr_array[0] = "ou";
7288 attr_array[1] = NULL;
7289 }
7290
7291 while (1)
7292 {
7293 if ((rc = linklist_build(ldap_handle, dName, filter, attr_array,
7294 &group_base, &group_count,
7295 LDAP_SCOPE_SUBTREE)) != LDAP_SUCCESS)
7296 {
7297 break;
7298 }
7299
7300 if (group_count == 0)
7301 break;
7302
7303 pPtr = group_base;
7304
7305 while(pPtr)
7306 {
7307 if (!strcasecmp(pPtr->attribute, "cn"))
7308 {
7309 sprintf(new_cn, "cn=%s", pPtr->value);
7310 if (i == 0)
7311 sprintf(temp, "%s,%s", orphans_other_ou, dn_path);
7312 if (i == 1)
7313 sprintf(temp, "%s,%s", orphans_machines_ou, dn_path);
7314 count = 1;
7315
7316 while (1)
7317 {
7318 rc = ldap_rename_s(ldap_handle, pPtr->dn, new_cn, temp,
7319 TRUE, NULL, NULL);
7320 if (rc == LDAP_ALREADY_EXISTS)
7321 {
7322 sprintf(new_cn, "cn=%s_%d", pPtr->value, count);
7323 ++count;
7324 }
7325 else
7326 break;
7327 }
7328 }
7329 else if (!strcasecmp(pPtr->attribute, "ou"))
7330 {
7331 rc = ldap_delete_s(ldap_handle, pPtr->dn);
7332 }
7333
7334 pPtr = pPtr->next;
7335 }
7336
7337 linklist_free(group_base);
7338 group_base = NULL;
7339 group_count = 0;
7340 }
7341 }
7342
7343 return(0);
7344}
7345
7346int get_machine_ou(LDAP *ldap_handle, char *dn_path, char *member,
7347 char *machine_ou, char *NewMachineName)
7348{
7349 LK_ENTRY *group_base;
7350 int group_count;
7351 int i;
7352 char filter[128];
7353 char *attr_array[3];
7354 char cn[256];
7355 char dn[256];
7356 char temp[256];
7357 char *pPtr;
7358 int rc;
7359
7360 strcpy(NewMachineName, member);
7361 rc = moira_connect();
7362 rc = GetMachineName(NewMachineName);
7363 moira_disconnect();
7364
7365 if (strlen(NewMachineName) == 0)
7366 {
7367 com_err(whoami, 0, "Unable to find alais for machine %s in Moira",
7368 member);
7369 return(1);
7370 }
7371
7372 pPtr = NULL;
7373 pPtr = strchr(NewMachineName, '.');
7374
7375 if (pPtr != NULL)
7376 (*pPtr) = '\0';
7377
7378 group_base = NULL;
7379 group_count = 0;
7380 sprintf(filter, "(sAMAccountName=%s$)", NewMachineName);
7381 attr_array[0] = "cn";
7382 attr_array[1] = NULL;
7383 sprintf(temp, "%s", dn_path);
7384
7385 if ((rc = linklist_build(ldap_handle, temp, filter, attr_array,
7386 &group_base, &group_count,
7387 LDAP_SCOPE_SUBTREE)) != 0)
7388 {
7389 com_err(whoami, 0, "Unable to process machine %s : %s",
7390 member, ldap_err2string(rc));
7391 return(1);
7392 }
7393
7394 if (group_count != 1)
7395 {
7396 com_err(whoami, 0,
7397 "Unable to process machine %s : machine not found in AD",
7398 NewMachineName);
7399 return(1);
7400 }
7401
7402 strcpy(dn, group_base->dn);
7403 strcpy(cn, group_base->value);
7404
7405 for (i = 0; i < (int)strlen(dn); i++)
7406 dn[i] = tolower(dn[i]);
7407
7408 for (i = 0; i < (int)strlen(cn); i++)
7409 cn[i] = tolower(cn[i]);
7410
7411 linklist_free(group_base);
7412 pPtr = NULL;
7413 pPtr = strstr(dn, cn);
7414
7415 if (pPtr == NULL)
7416 {
7417 com_err(whoami, 0, "Unable to process machine %s",
7418 member);
7419 return(1);
7420 }
7421
7422 pPtr += strlen(cn) + 1;
7423 strcpy(machine_ou, pPtr);
7424 pPtr = NULL;
7425 pPtr = strstr(machine_ou, "dc=");
7426
7427 if (pPtr == NULL)
7428 {
7429 com_err(whoami, 0, "Unable to process machine %s",
7430 member);
7431 return(1);
7432 }
7433
7434 --pPtr;
7435 (*pPtr) = '\0';
7436
7437 return(0);
7438}
7439
7440int machine_move_to_ou(LDAP *ldap_handle, char * dn_path,
7441 char *MoiraMachineName, char *DestinationOu)
7442{
7443 char NewCn[128];
7444 char OldDn[512];
7445 char MachineName[128];
7446 char filter[128];
7447 char *attr_array[3];
7448 char NewOu[256];
7449 char *cPtr = NULL;
7450 int group_count;
7451 long rc;
7452 LK_ENTRY *group_base;
7453
7454 group_count = 0;
7455 group_base = NULL;
7456
7457 strcpy(MachineName, MoiraMachineName);
7458 rc = GetMachineName(MachineName);
7459
7460 if (strlen(MachineName) == 0)
7461 {
7462 com_err(whoami, 0, "Unable to find alais for machine %s in Moira",
7463 MoiraMachineName);
7464 return(1);
7465 }
7466
7467 cPtr = strchr(MachineName, '.');
7468
7469 if (cPtr != NULL)
7470 (*cPtr) = '\0';
7471
7472 sprintf(filter, "(sAMAccountName=%s$)", MachineName);
7473 attr_array[0] = "sAMAccountName";
7474 attr_array[1] = NULL;
7475
7476 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
7477 &group_base,
7478 &group_count, LDAP_SCOPE_SUBTREE)) != 0)
7479 {
7480 com_err(whoami, 0, "Unable to process machine %s : %s",
7481 MoiraMachineName, ldap_err2string(rc));
7482 return(1);
7483 }
7484
7485 if (group_count == 1)
7486 strcpy(OldDn, group_base->dn);
7487
7488 linklist_free(group_base);
7489 group_base = NULL;
7490
7491 if (group_count != 1)
7492 {
7493 com_err(whoami, 0, "Unable to find machine %s in AD: %s",
7494 MoiraMachineName);
7495 return(1);
7496 }
7497
7498 sprintf(NewOu, "%s,%s", DestinationOu, dn_path);
7499 cPtr = strchr(OldDn, ',');
7500
7501 if (cPtr != NULL)
7502 {
7503 ++cPtr;
7504 if (!strcasecmp(cPtr, NewOu))
7505 return(0);
7506 }
7507
7508 sprintf(NewCn, "CN=%s", MachineName);
7509 rc = ldap_rename_s(ldap_handle, OldDn, NewCn, NewOu, TRUE, NULL, NULL);
7510
7511 return(rc);
7512}
7513
7514int machine_check(LDAP *ldap_handle, char *dn_path, char *machine_name)
7515{
7516 char Name[128];
7517 char *pPtr;
7518 int rc;
7519
7520 memset(Name, '\0', sizeof(Name));
7521 strcpy(Name, machine_name);
7522 pPtr = NULL;
7523 pPtr = strchr(Name, '.');
7524
7525 if (pPtr != NULL)
7526 (*pPtr) = '\0';
7527
7528 strcat(Name, "$");
7529 return(!(rc = checkADname(ldap_handle, dn_path, Name)));
7530}
7531
7532int machine_get_moira_container(LDAP *ldap_handle, char *dn_path,
7533 char *machine_name, char *container_name)
7534{
7535 int rc;
7536 char *av[2];
7537 char *call_args[2];
7538
7539 av[0] = machine_name;
7540 call_args[0] = (char *)container_name;
7541 rc = mr_query("get_machine_to_container_map", 1, av,
7542 machine_GetMoiraContainer, call_args);
7543 return(rc);
7544}
7545
7546int machine_GetMoiraContainer(int ac, char **av, void *ptr)
7547{
7548 char **call_args;
7549
7550 call_args = ptr;
7551 strcpy(call_args[0], av[1]);
7552 return(0);
7553}
7554
7555int Moira_container_group_create(char **after)
7556{
7557 long rc;
7558 char GroupName[64];
7559 char *argv[20];
7560
7561 memset(GroupName, '\0', sizeof(GroupName));
7562 rc = Moira_groupname_create(GroupName, after[CONTAINER_NAME],
7563 after[CONTAINER_ROWID]);
7564 if (rc)
7565 return rc;
7566
7567 argv[L_NAME] = GroupName;
7568 argv[L_ACTIVE] = "1";
7569 argv[L_PUBLIC] = "0";
7570 argv[L_HIDDEN] = "0";
7571 argv[L_MAILLIST] = "0";
7572 argv[L_GROUP] = "1";
7573 argv[L_GID] = UNIQUE_GID;
7574 argv[L_NFSGROUP] = "0";
7575 argv[L_MAILMAN] = "0";
7576 argv[L_MAILMAN_SERVER] = "[NONE]";
7577 argv[L_DESC] = "auto created container group";
7578 argv[L_ACE_TYPE] = "USER";
7579 argv[L_MEMACE_TYPE] = "USER";
7580 argv[L_ACE_NAME] = "sms";
7581 argv[L_MEMACE_NAME] = "sms";
7582
7583 if (rc = mr_query("add_list", 15, argv, NULL, NULL))
7584 {
7585 com_err(whoami, 0,
7586 "Unable to create container group %s for container %s: %s",
7587 GroupName, after[CONTAINER_NAME], error_message(rc));
7588 }
7589
7590 Moira_setContainerGroup(after[CONTAINER_NAME], GroupName);
7591 Moira_addGroupToParent(after[CONTAINER_NAME], GroupName);
7592
7593 return(rc);
7594}
7595
7596int Moira_container_group_update(char **before, char **after)
7597{
7598 long rc;
7599 char BeforeGroupName[64];
7600 char AfterGroupName[64];
7601 char *argv[20];
7602
7603 if (!strcasecmp(after[CONTAINER_NAME], before[CONTAINER_NAME]))
7604 return(0);
7605
7606 memset(BeforeGroupName, '\0', sizeof(BeforeGroupName));
7607 Moira_getGroupName(after[CONTAINER_NAME], BeforeGroupName, 0);
7608 if (strlen(BeforeGroupName) == 0)
7609 return(0);
7610
7611 memset(AfterGroupName, '\0', sizeof(AfterGroupName));
7612 rc = Moira_groupname_create(AfterGroupName, after[CONTAINER_NAME],
7613 after[CONTAINER_ROWID]);
7614 if (rc)
7615 return rc;
7616
7617 if (strcasecmp(BeforeGroupName, AfterGroupName))
7618 {
7619 argv[L_NAME] = BeforeGroupName;
7620 argv[L_NAME + 1] = AfterGroupName;
7621 argv[L_ACTIVE + 1] = "1";
7622 argv[L_PUBLIC + 1] = "0";
7623 argv[L_HIDDEN + 1] = "0";
7624 argv[L_MAILLIST + 1] = "0";
7625 argv[L_GROUP + 1] = "1";
7626 argv[L_GID + 1] = UNIQUE_GID;
7627 argv[L_NFSGROUP + 1] = "0";
7628 argv[L_MAILMAN + 1] = "0";
7629 argv[L_MAILMAN_SERVER + 1] = "[NONE]";
7630 argv[L_DESC + 1] = "auto created container group";
7631 argv[L_ACE_TYPE + 1] = "USER";
7632 argv[L_MEMACE_TYPE + 1] = "USER";
7633 argv[L_ACE_NAME + 1] = "sms";
7634 argv[L_MEMACE_NAME + 1] = "sms";
7635
7636 if (rc = mr_query("update_list", 16, argv, NULL, NULL))
7637 {
7638 com_err(whoami, 0,
7639 "Unable to rename container group from %s to %s: %s",
7640 BeforeGroupName, AfterGroupName, error_message(rc));
7641 }
7642 }
7643
7644 return(rc);
7645}
7646
7647int Moira_container_group_delete(char **before)
7648{
7649 long rc = 0;
7650 char *argv[13];
7651 char GroupName[64];
7652 char ParentGroupName[64];
7653
7654 memset(ParentGroupName, '\0', sizeof(ParentGroupName));
7655 Moira_getGroupName(before[CONTAINER_NAME], ParentGroupName, 1);
7656
7657 memset(GroupName, '\0', sizeof(GroupName));
7658
7659 if (strcmp(before[CONTAINER_GROUP_NAME], "[none]"))
7660 strcpy(GroupName, before[CONTAINER_GROUP_NAME]);
7661
7662 if ((strlen(ParentGroupName) != 0) && (strlen(GroupName) != 0))
7663 {
7664 argv[0] = ParentGroupName;
7665 argv[1] = "LIST";
7666 argv[2] = GroupName;
7667
7668 if (rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL))
7669 {
7670 com_err(whoami, 0,
7671 "Unable to delete container group %s from list: %s",
7672 GroupName, ParentGroupName, error_message(rc));
7673 }
7674 }
7675
7676 if (strlen(GroupName) != 0)
7677 {
7678 argv[0] = GroupName;
7679
7680 if (rc = mr_query("delete_list", 1, argv, NULL, NULL))
7681 {
7682 com_err(whoami, 0, "Unable to delete container group %s : %s",
7683 GroupName, error_message(rc));
7684 }
7685 }
7686
7687 return(rc);
7688}
7689
7690int Moira_groupname_create(char *GroupName, char *ContainerName,
7691 char *ContainerRowID)
7692{
7693 char *ptr;
7694 char *ptr1;
7695 char temp[64];
7696 char newGroupName[64];
7697 char tempGroupName[64];
7698 char tempgname[64];
7699 char *argv[1];
7700 int i;
7701 long rc;
7702
7703 strcpy(temp, ContainerName);
7704
7705 ptr1 = strrchr(temp, '/');
7706
7707 if (ptr1 != NULL)
7708 {
7709 *ptr1 = '\0';
7710 ptr = ++ptr1;
7711 ptr1 = strrchr(temp, '/');
7712
7713 if (ptr1 != NULL)
7714 {
7715 sprintf(tempgname, "%s-%s", ++ptr1, ptr);
7716 }
7717 else
7718 strcpy(tempgname, ptr);
7719 }
7720 else
7721 strcpy(tempgname, temp);
7722
7723 if (strlen(tempgname) > 25)
7724 tempgname[25] ='\0';
7725
7726 sprintf(newGroupName, "cnt-%s", tempgname);
7727
7728 /* change everything to lower case */
7729 ptr = newGroupName;
7730
7731 while (*ptr)
7732 {
7733 if (isupper(*ptr))
7734 *ptr = tolower(*ptr);
7735
7736 if (*ptr == ' ')
7737 *ptr = '-';
7738
7739 ptr++;
7740 }
7741
7742 strcpy(tempGroupName, newGroupName);
7743 i = (int)'0';
7744
7745 /* append 0-9 then a-z if a duplicate is found */
7746 while(1)
7747 {
7748 argv[0] = newGroupName;
7749
7750 if (rc = mr_query("get_list_info", 1, argv, NULL, NULL))
7751 {
7752 if (rc == MR_NO_MATCH)
7753 break;
7754 com_err(whoami, 0, "Moira error while creating group name for "
7755 "container %s : %s", ContainerName, error_message(rc));
7756 return rc;
7757 }
7758
7759 sprintf(newGroupName, "%s-%c", tempGroupName, i);
7760
7761 if (i == (int)'z')
7762 {
7763 com_err(whoami, 0, "Unable to find a unique group name for "
7764 "container %s: too many duplicate container names",
7765 ContainerName);
7766 return 1;
7767 }
7768
7769 if (i == '9')
7770 i = 'a';
7771 else
7772 i++;
7773 }
7774
7775 strcpy(GroupName, newGroupName);
7776 return(0);
7777}
7778
7779int Moira_setContainerGroup(char *origContainerName, char *GroupName)
7780{
7781 long rc;
7782 char *argv[3];
7783
7784 argv[0] = origContainerName;
7785 argv[1] = GroupName;
7786
7787 if ((rc = mr_query("set_container_list", 2, argv, NULL, NULL)))
7788 {
7789 com_err(whoami, 0,
7790 "Unable to set container group %s in container %s: %s",
7791 GroupName, origContainerName, error_message(rc));
7792 }
7793
7794 return(0);
7795}
7796
7797int Moira_addGroupToParent(char *origContainerName, char *GroupName)
7798 {
7799 char ContainerName[64];
7800 char ParentGroupName[64];
7801 char *argv[3];
7802 long rc;
7803
7804 strcpy(ContainerName, origContainerName);
7805
7806 Moira_getGroupName(ContainerName, ParentGroupName, 1);
7807
7808 /* top-level container */
7809 if (strlen(ParentGroupName) == 0)
7810 return(0);
7811
7812 argv[0] = ParentGroupName;
7813 argv[1] = "LIST";
7814 argv[2] = GroupName;
7815
7816 if ((rc = mr_query("add_member_to_list", 3, argv, NULL, NULL)))
7817 {
7818 com_err(whoami, 0,
7819 "Unable to add container group %s to parent group %s: %s",
7820 GroupName, ParentGroupName, error_message(rc));
7821 }
7822
7823 return(0);
7824 }
7825
7826int Moira_getContainerGroup(int ac, char **av, void *ptr)
7827{
7828 char **call_args;
7829
7830 call_args = ptr;
7831 strcpy(call_args[0], av[1]);
7832
7833 return(0);
7834}
7835
7836int Moira_getGroupName(char *origContainerName, char *GroupName,
7837 int ParentFlag)
7838{
7839 char ContainerName[64];
7840 char *argv[3];
7841 char *call_args[3];
7842 char *ptr;
7843 long rc;
7844
7845 strcpy(ContainerName, origContainerName);
7846
7847 if (ParentFlag)
7848 {
7849 ptr = strrchr(ContainerName, '/');
7850
7851 if (ptr != NULL)
7852 (*ptr) = '\0';
7853 else
7854 return(0);
7855 }
7856
7857 argv[0] = ContainerName;
7858 argv[1] = NULL;
7859 call_args[0] = GroupName;
7860 call_args[1] = NULL;
7861
7862 if (!(rc = mr_query("get_container_list", 1, argv, Moira_getContainerGroup,
7863 call_args)))
7864 {
7865 if (strlen(GroupName) != 0)
7866 return(0);
7867 }
7868
7869 if (rc)
7870 com_err(whoami, 0, "Unable to get container group from container %s: %s",
7871 ContainerName, error_message(rc));
7872 else
7873 com_err(whoami, 0, "Unable to get container group from container %s",
7874 ContainerName);
7875
7876 return(0);
7877}
7878
7879int Moira_process_machine_container_group(char *MachineName, char* GroupName,
7880 int DeleteMachine)
7881{
7882 char *argv[3];
7883 long rc;
7884
7885 if (strcmp(GroupName, "[none]") == 0)
7886 return 0;
7887
7888 argv[0] = GroupName;
7889 argv[1] = "MACHINE";
7890 argv[2] = MachineName;
7891
7892 if (!DeleteMachine)
7893 rc = mr_query("add_member_to_list", 3, argv, NULL, NULL);
7894 else
7895 rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL);
7896
7897 if (rc)
7898 {
7899 com_err(whoami, 0, "Unable to add machine %s to container group%s: %s",
7900 MachineName, GroupName, error_message(rc));
7901 }
7902
7903 return(0);
7904}
7905
7906int GetMachineName(char *MachineName)
7907{
7908 char *args[2];
7909 char NewMachineName[1024];
7910 char *szDot;
7911 int rc = 0;
7912 int i;
7913 DWORD dwLen = 0;
7914 char *call_args[2];
7915
7916 // If the address happens to be in the top-level MIT domain, great!
7917 strcpy(NewMachineName, MachineName);
7918
7919 for (i = 0; i < (int)strlen(NewMachineName); i++)
7920 NewMachineName[i] = toupper(NewMachineName[i]);
7921
7922 szDot = strchr(NewMachineName,'.');
7923
7924 if ((szDot) && (!strcasecmp(szDot+1, DOMAIN_SUFFIX)))
7925 {
7926 return(0);
7927 }
7928
7929 // If not, see if it has a Moira alias in the top-level MIT domain.
7930 memset(NewMachineName, '\0', sizeof(NewMachineName));
7931 args[0] = "*";
7932 args[1] = MachineName;
7933 call_args[0] = NewMachineName;
7934 call_args[1] = NULL;
7935
7936 if (rc = mr_query("get_hostalias", 2, args, ProcessMachineName, call_args))
7937 {
7938 com_err(whoami, 0, "Unable to resolve machine name %s : %s",
7939 MachineName, error_message(rc));
7940 strcpy(MachineName, "");
7941 return(0);
7942 }
7943
7944 if (strlen(NewMachineName) != 0)
7945 strcpy(MachineName, NewMachineName);
7946 else
7947 strcpy(MachineName, "");
7948
7949 return(0);
7950}
7951
7952int ProcessMachineName(int ac, char **av, void *ptr)
7953{
7954 char **call_args;
7955 char MachineName[1024];
7956 char *szDot;
7957 int i;
7958
7959 call_args = ptr;
7960
7961 if (strlen(call_args[0]) == 0)
7962 {
7963 strcpy(MachineName, av[0]);
7964
7965 for (i = 0; i < (int)strlen(MachineName); i++)
7966 MachineName[i] = toupper(MachineName[i]);
7967
7968 szDot = strchr(MachineName,'.');
7969
7970 if ((szDot) && (!strcasecmp(szDot+1,DOMAIN_SUFFIX)))
7971 {
7972 strcpy(call_args[0], MachineName);
7973 }
7974 }
7975
7976 return(0);
7977}
7978
7979void SwitchSFU(LDAPMod **mods, int *UseSFU30, int n)
7980{
7981 int i;
7982
7983 if (*UseSFU30)
7984 {
7985 for (i = 0; i < n; i++)
7986 {
7987 if (!strcmp(mods[i]->mod_type, "msSFU30UidNumber"))
7988 mods[i]->mod_type = "uidNumber";
7989 }
7990
7991 (*UseSFU30) = 0;
7992 }
7993 else
7994 {
7995 for (i = 0; i < n; i++)
7996 {
7997 if (!strcmp(mods[i]->mod_type, "uidNumber"))
7998 mods[i]->mod_type = "msSFU30UidNumber";
7999 }
8000
8001 (*UseSFU30) = 1;
8002 }
8003}
8004
8005int SetHomeDirectory(LDAP *ldap_handle, char *user_name,
8006 char *DistinguishedName,
8007 char *WinHomeDir, char *WinProfileDir,
8008 char **homedir_v, char **winProfile_v,
8009 char **drives_v, LDAPMod **mods,
8010 int OpType, int n)
8011{
8012 char **hp;
8013 char cWeight[3];
8014 char cPath[1024];
8015 char path[1024];
8016 char winPath[1024];
8017 char winProfile[1024];
8018 char homeDrive[8];
8019 char homedir[1024];
8020 char apple_homedir[1024];
8021 char *apple_homedir_v[] = {NULL, NULL};
8022 int last_weight;
8023 int i;
8024 int rc;
8025 LDAPMod *DelMods[20];
8026
8027 memset(homeDrive, '\0', sizeof(homeDrive));
8028 memset(path, '\0', sizeof(path));
8029 memset(winPath, '\0', sizeof(winPath));
8030 memset(winProfile, '\0', sizeof(winProfile));
8031 hp = NULL;
8032
8033 if(!ActiveDirectory)
8034 {
8035 if ((hp = hes_resolve(user_name, "filsys")) != NULL)
8036 {
8037 memset(cWeight, 0, sizeof(cWeight));
8038 memset(cPath, 0, sizeof(cPath));
8039 last_weight = 1000;
8040 i = 0;
8041
8042 while (hp[i] != NULL)
8043 {
8044 if (sscanf(hp[i], "%*s %s", cPath))
8045 {
8046 if (strnicmp(cPath, AFS, strlen(AFS)) == 0)
8047 {
8048 if (sscanf(hp[i], "%*s %*s %*s %*s %s", cWeight))
8049 {
8050 if (atoi(cWeight) < last_weight)
8051 {
8052 strcpy(path, cPath);
8053 last_weight = (int)atoi(cWeight);
8054 }
8055 }
8056 else
8057 strcpy(path, cPath);
8058 }
8059 }
8060 ++i;
8061 }
8062
8063 if (strlen(path))
8064 {
8065 if (!strnicmp(path, AFS, strlen(AFS)))
8066 {
8067 sprintf(homedir, "%s", path);
8068 sprintf(apple_homedir, "%s/MacData", path);
8069 homedir_v[0] = homedir;
8070 apple_homedir_v[0] = apple_homedir;
8071 ADD_ATTR("homeDirectory", homedir_v, OpType);
8072 ADD_ATTR("apple-user-homeDirectory", apple_homedir_v,
8073 OpType);
8074 }
8075 }
8076 else
8077 {
8078 if(user_name[0] && user_name[1])
8079 {
8080 sprintf(homedir, "/afs/athena.mit.edu/user/%c/%c/%s",
8081 user_name[0], user_name[1], user_name);
8082 sprintf(apple_homedir, "%s/MacData", homedir);
8083 homedir_v[0] = "NONE";
8084 apple_homedir_v[0] = "NONE";
8085 ADD_ATTR("homeDirectory", homedir_v, OpType);
8086 ADD_ATTR("apple-user-homeDirectory", apple_homedir_v,
8087 OpType);
8088 }
8089 }
8090 }
8091 else
8092 {
8093 if(user_name[0] && user_name[1])
8094 {
8095 sprintf(homedir, "/afs/athena.mit.edu/user/%c/%c/%s",
8096 user_name[0], user_name[1], user_name);
8097 sprintf(apple_homedir, "%s/MacData", homedir);
8098 homedir_v[0] = "NONE";
8099 apple_homedir_v[0] = "NONE";
8100 ADD_ATTR("homeDirectory", homedir_v, OpType);
8101 ADD_ATTR("apple-user-homeDirectory", apple_homedir_v,
8102 OpType);
8103 }
8104 }
8105 return(n);
8106 }
8107
8108 if ((!strcasecmp(WinHomeDir, "[afs]")) ||
8109 (!strcasecmp(WinProfileDir, "[afs]")))
8110 {
8111 if ((hp = hes_resolve(user_name, "filsys")) != NULL)
8112 {
8113 memset(cWeight, 0, sizeof(cWeight));
8114 memset(cPath, 0, sizeof(cPath));
8115 last_weight = 1000;
8116 i = 0;
8117
8118 while (hp[i] != NULL)
8119 {
8120 if (sscanf(hp[i], "%*s %s", cPath))
8121 {
8122 if (strnicmp(cPath, AFS, strlen(AFS)) == 0)
8123 {
8124 if (sscanf(hp[i], "%*s %*s %*s %*s %s", cWeight))
8125 {
8126 if (atoi(cWeight) < last_weight)
8127 {
8128 strcpy(path, cPath);
8129 last_weight = (int)atoi(cWeight);
8130 }
8131 }
8132 else
8133 strcpy(path, cPath);
8134 }
8135 }
8136 ++i;
8137 }
8138
8139 if (strlen(path))
8140 {
8141 if (!strnicmp(path, AFS, strlen(AFS)))
8142 {
8143 AfsToWinAfs(path, winPath);
8144 strcpy(winProfile, winPath);
8145 strcat(winProfile, "\\.winprofile");
8146 }
8147 }
8148 }
8149 else
8150 return(n);
8151 }
8152
8153 if ((!strcasecmp(WinHomeDir, "[dfs]")) ||
8154 (!strcasecmp(WinProfileDir, "[dfs]")))
8155 {
8156 sprintf(path, "\\\\%s\\dfs\\profiles\\%c\\%s", ldap_domain,
8157 user_name[0], user_name);
8158
8159 if (!strcasecmp(WinProfileDir, "[dfs]"))
8160 {
8161 strcpy(winProfile, path);
8162 strcat(winProfile, "\\.winprofile");
8163 }
8164
8165 if (!strcasecmp(WinHomeDir, "[dfs]"))
8166 strcpy(winPath, path);
8167 }
8168
8169 if (hp != NULL)
8170 {
8171 i = 0;
8172 while (hp[i])
8173 {
8174 free(hp[i]);
8175 i++;
8176 }
8177 }
8178
8179 if (!strcasecmp(WinHomeDir, "[local]"))
8180 memset(winPath, '\0', sizeof(winPath));
8181 else if (!strcasecmp(WinHomeDir, "[afs]") ||
8182 !strcasecmp(WinHomeDir, "[dfs]"))
8183 {
8184 strcpy(homeDrive, "H:");
8185 }
8186 else
8187 {
8188 strcpy(winPath, WinHomeDir);
8189 if (!strncmp(WinHomeDir, "\\\\", 2))
8190 {
8191 strcpy(homeDrive, "H:");
8192 }
8193 }
8194
8195 // nothing needs to be done if WinProfileDir is [afs].
8196 if (!strcasecmp(WinProfileDir, "[local]"))
8197 memset(winProfile, '\0', sizeof(winProfile));
8198 else if (strcasecmp(WinProfileDir, "[afs]") &&
8199 strcasecmp(WinProfileDir, "[dfs]"))
8200 {
8201 strcpy(winProfile, WinProfileDir);
8202 }
8203
8204 if (strlen(winProfile) != 0)
8205 {
8206 if (winProfile[strlen(winProfile) - 1] == '\\')
8207 winProfile[strlen(winProfile) - 1] = '\0';
8208 }
8209
8210 if (strlen(winPath) != 0)
8211 {
8212 if (winPath[strlen(winPath) - 1] == '\\')
8213 winPath[strlen(winPath) - 1] = '\0';
8214 }
8215
8216 if ((winProfile[1] == ':') && (strlen(winProfile) == 2))
8217 strcat(winProfile, "\\");
8218
8219 if ((winPath[1] == ':') && (strlen(winPath) == 2))
8220 strcat(winPath, "\\");
8221
8222 if (strlen(winPath) == 0)
8223 {
8224 if (OpType == LDAP_MOD_REPLACE)
8225 {
8226 i = 0;
8227 DEL_ATTR("homeDirectory", LDAP_MOD_DELETE);
8228 DelMods[i] = NULL;
8229 //unset homeDirectory attribute for user.
8230 rc = ldap_modify_s(ldap_handle, DistinguishedName, DelMods);
8231 free(DelMods[0]);
8232 }
8233 }
8234 else
8235 {
8236 homedir_v[0] = strdup(winPath);
8237 ADD_ATTR("homeDirectory", homedir_v, OpType);
8238 }
8239
8240 if (strlen(winProfile) == 0)
8241 {
8242 if (OpType == LDAP_MOD_REPLACE)
8243 {
8244 i = 0;
8245 DEL_ATTR("profilePath", LDAP_MOD_DELETE);
8246 DelMods[i] = NULL;
8247 //unset profilePate attribute for user.
8248 rc = ldap_modify_s(ldap_handle, DistinguishedName, DelMods);
8249 free(DelMods[0]);
8250 }
8251 }
8252 else
8253 {
8254 winProfile_v[0] = strdup(winProfile);
8255 ADD_ATTR("profilePath", winProfile_v, OpType);
8256 }
8257
8258 if (strlen(homeDrive) == 0)
8259 {
8260 if (OpType == LDAP_MOD_REPLACE)
8261 {
8262 i = 0;
8263 DEL_ATTR("homeDrive", LDAP_MOD_DELETE);
8264 DelMods[i] = NULL;
8265 //unset homeDrive attribute for user
8266 rc = ldap_modify_s(ldap_handle, DistinguishedName, DelMods);
8267 free(DelMods[0]);
8268 }
8269 }
8270 else
8271 {
8272 drives_v[0] = strdup(homeDrive);
8273 ADD_ATTR("homeDrive", drives_v, OpType);
8274 }
8275
8276 return(n);
8277}
8278
8279int attribute_update(LDAP *ldap_handle, char *distinguished_name,
8280 char *attribute_value, char *attribute, char *user_name)
8281{
8282 char *mod_v[] = {NULL, NULL};
8283 LDAPMod *DelMods[20];
8284 LDAPMod *mods[20];
8285 int n;
8286 int i;
8287 int rc;
8288
8289 if (strlen(attribute_value) == 0)
8290 {
8291 i = 0;
8292 DEL_ATTR(attribute, LDAP_MOD_DELETE);
8293 DelMods[i] = NULL;
8294 rc = ldap_modify_s(ldap_handle, distinguished_name, DelMods);
8295 free(DelMods[0]);
8296 }
8297 else
8298 {
8299 n = 0;
8300 mod_v[0] = attribute_value;
8301 ADD_ATTR(attribute, mod_v, LDAP_MOD_REPLACE);
8302 mods[n] = NULL;
8303
8304 if ((rc = ldap_modify_s(ldap_handle, distinguished_name,
8305 mods)) != LDAP_SUCCESS)
8306 {
8307 free(mods[0]);
8308 n = 0;
8309 mod_v[0] = attribute_value;
8310 ADD_ATTR(attribute, mod_v, LDAP_MOD_ADD);
8311 mods[n] = NULL;
8312
8313 if ((rc = ldap_modify_s(ldap_handle, distinguished_name,
8314 mods)) != LDAP_SUCCESS)
8315 {
8316 com_err(whoami, 0, "Unable to change the %s attribute for %s "
8317 "in the AD : %s",
8318 attribute, user_name, ldap_err2string(rc));
8319 }
8320 }
8321
8322 free(mods[0]);
8323 }
8324
8325 return(rc);
8326}
8327
8328void StringTrim(char *StringToTrim)
8329{
8330 char *t, *s;
8331 char *save;
8332
8333 save = strdup(StringToTrim);
8334
8335 s = save;
8336
8337 while (isspace(*s))
8338 s++;
8339
8340 /* skip to end of string */
8341 if (*s == '\0')
8342 {
8343 if (*save)
8344 *save = '\0';
8345 strcpy(StringToTrim, save);
8346 return;
8347 }
8348
8349 for (t = s; *t; t++)
8350 continue;
8351
8352 while (t > s)
8353 {
8354 --t;
8355 if (!isspace(*t))
8356 {
8357 t++;
8358 break;
8359 }
8360 }
8361
8362 if (*t)
8363 *t = '\0';
8364
8365 strcpy(StringToTrim, s);
8366 return;
8367}
8368
8369int ReadConfigFile(char *DomainName)
8370{
8371 int Count;
8372 int i;
8373 int k;
8374 char temp[256];
8375 char temp1[256];
8376 FILE *fptr;
8377
8378 Count = 0;
8379
8380 sprintf(temp, "%s%s.cfg", CFG_PATH, DomainName);
8381
8382 if ((fptr = fopen(temp, "r")) != NULL)
8383 {
8384 while (fgets(temp, sizeof(temp), fptr) != 0)
8385 {
8386 for (i = 0; i < (int)strlen(temp); i++)
8387 temp[i] = toupper(temp[i]);
8388
8389 if (temp[strlen(temp) - 1] == '\n')
8390 temp[strlen(temp) - 1] = '\0';
8391
8392 StringTrim(temp);
8393
8394 if (strlen(temp) == 0)
8395 continue;
8396
8397 if (!strncmp(temp, DOMAIN, strlen(DOMAIN)))
8398 {
8399 if (strlen(temp) > (strlen(DOMAIN)))
8400 {
8401 strcpy(ldap_domain, &temp[strlen(DOMAIN)]);
8402 StringTrim(ldap_domain);
8403 }
8404 }
8405 else if (!strncmp(temp, REALM, strlen(REALM)))
8406 {
8407 if (strlen(temp) > (strlen(REALM)))
8408 {
8409 strcpy(ldap_realm, &temp[strlen(REALM)]);
8410 StringTrim(ldap_realm);
8411 }
8412 }
8413 else if (!strncmp(temp, PORT, strlen(PORT)))
8414 {
8415 if (strlen(temp) > (strlen(PORT)))
8416 {
8417 strcpy(ldap_port, &temp[strlen(PORT)]);
8418 StringTrim(ldap_port);
8419 }
8420 }
8421 else if (!strncmp(temp, PRINCIPALNAME, strlen(PRINCIPALNAME)))
8422 {
8423 if (strlen(temp) > (strlen(PRINCIPALNAME)))
8424 {
8425 strcpy(PrincipalName, &temp[strlen(PRINCIPALNAME)]);
8426 StringTrim(PrincipalName);
8427 }
8428 }
8429 else if (!strncmp(temp, SERVER, strlen(SERVER)))
8430 {
8431 if (strlen(temp) > (strlen(SERVER)))
8432 {
8433 ServerList[Count] = calloc(1, 256);
8434 strcpy(ServerList[Count], &temp[strlen(SERVER)]);
8435 StringTrim(ServerList[Count]);
8436 ++Count;
8437 }
8438 }
8439 else if (!strncmp(temp, MSSFU, strlen(MSSFU)))
8440 {
8441 if (strlen(temp) > (strlen(MSSFU)))
8442 {
8443 strcpy(temp1, &temp[strlen(MSSFU)]);
8444 StringTrim(temp1);
8445 if (!strcmp(temp1, SFUTYPE))
8446 UseSFU30 = 1;
8447 }
8448 }
8449 else if (!strncmp(temp, GROUP_SUFFIX, strlen(GROUP_SUFFIX)))
8450 {
8451 if (strlen(temp) > (strlen(GROUP_SUFFIX)))
8452 {
8453 strcpy(temp1, &temp[strlen(GROUP_SUFFIX)]);
8454 StringTrim(temp1);
8455 if (!strcasecmp(temp1, "NO"))
8456 {
8457 UseGroupSuffix = 0;
8458 memset(group_suffix, '\0', sizeof(group_suffix));
8459 }
8460 }
8461 }
8462 else if (!strncmp(temp, GROUP_TYPE, strlen(GROUP_TYPE)))
8463 {
8464 if (strlen(temp) > (strlen(GROUP_TYPE)))
8465 {
8466 strcpy(temp1, &temp[strlen(GROUP_TYPE)]);
8467 StringTrim(temp1);
8468 if (!strcasecmp(temp1, "UNIVERSAL"))
8469 UseGroupUniversal = 1;
8470 }
8471 }
8472 else if (!strncmp(temp, SET_GROUP_ACE, strlen(SET_GROUP_ACE)))
8473 {
8474 if (strlen(temp) > (strlen(SET_GROUP_ACE)))
8475 {
8476 strcpy(temp1, &temp[strlen(SET_GROUP_ACE)]);
8477 StringTrim(temp1);
8478 if (!strcasecmp(temp1, "NO"))
8479 SetGroupAce = 0;
8480 }
8481 }
8482 else if (!strncmp(temp, SET_PASSWORD, strlen(SET_PASSWORD)))
8483 {
8484 if (strlen(temp) > (strlen(SET_PASSWORD)))
8485 {
8486 strcpy(temp1, &temp[strlen(SET_PASSWORD)]);
8487 StringTrim(temp1);
8488 if (!strcasecmp(temp1, "NO"))
8489 SetPassword = 0;
8490 }
8491 }
8492 else if (!strncmp(temp, EXCHANGE, strlen(EXCHANGE)))
8493 {
8494 if (strlen(temp) > (strlen(EXCHANGE)))
8495 {
8496 strcpy(temp1, &temp[strlen(EXCHANGE)]);
8497 StringTrim(temp1);
8498 if (!strcasecmp(temp1, "YES"))
8499 Exchange = 1;
8500 }
8501 }
8502 else if (!strncmp(temp, PROCESS_MACHINE_CONTAINER,
8503 strlen(PROCESS_MACHINE_CONTAINER)))
8504 {
8505 if (strlen(temp) > (strlen(PROCESS_MACHINE_CONTAINER)))
8506 {
8507 strcpy(temp1, &temp[strlen(PROCESS_MACHINE_CONTAINER)]);
8508 StringTrim(temp1);
8509 if (!strcasecmp(temp1, "NO"))
8510 ProcessMachineContainer = 0;
8511 }
8512 }
8513 else if (!strncmp(temp, ACTIVE_DIRECTORY,
8514 strlen(ACTIVE_DIRECTORY)))
8515 {
8516 if (strlen(temp) > (strlen(ACTIVE_DIRECTORY)))
8517 {
8518 strcpy(temp1, &temp[strlen(ACTIVE_DIRECTORY)]);
8519 StringTrim(temp1);
8520 if (!strcasecmp(temp1, "NO"))
8521 ActiveDirectory = 0;
8522 }
8523 }
8524 else
8525 {
8526 if (strlen(ldap_domain) != 0)
8527 {
8528 memset(ldap_domain, '\0', sizeof(ldap_domain));
8529 break;
8530 }
8531
8532 if (strlen(temp) != 0)
8533 strcpy(ldap_domain, temp);
8534 }
8535 }
8536 fclose(fptr);
8537 }
8538
8539 if (strlen(ldap_domain) == 0)
8540 {
8541 strcpy(ldap_domain, DomainName);
8542 }
8543
8544 if (Count == 0)
8545 return(0);
8546
8547 for (i = 0; i < Count; i++)
8548 {
8549 if (ServerList[i] != 0)
8550 {
8551 for (k = 0; k < (int)strlen(ServerList[i]); k++)
8552 ServerList[i][k] = toupper(ServerList[i][k]);
8553 }
8554 }
8555
8556 return(0);
8557}
8558
8559int ReadDomainList()
8560{
8561 int Count;
8562 int i;
8563 char temp[128];
8564 char temp1[128];
8565 FILE *fptr;
8566 unsigned char c[11];
8567 unsigned char stuff[256];
8568 int rc;
8569 int ok;
8570
8571 Count = 0;
8572 sprintf(temp, "%s%s", CFG_PATH, WINADCFG);
8573
8574 if ((fptr = fopen(temp, "r")) != NULL)
8575 {
8576 while (fgets(temp, sizeof(temp), fptr) != 0)
8577 {
8578 for (i = 0; i < (int)strlen(temp); i++)
8579 temp[i] = toupper(temp[i]);
8580
8581 if (temp[strlen(temp) - 1] == '\n')
8582 temp[strlen(temp) - 1] = '\0';
8583
8584 StringTrim(temp);
8585
8586 if (strlen(temp) == 0)
8587 continue;
8588
8589 if (!strncmp(temp, DOMAIN, strlen(DOMAIN)))
8590 {
8591 if (strlen(temp) > (strlen(DOMAIN)))
8592 {
8593 strcpy(temp1, &temp[strlen(DOMAIN)]);
8594 StringTrim(temp1);
8595 strcpy(temp, temp1);
8596 }
8597 }
8598
8599 strcpy(DomainNames[Count], temp);
8600 StringTrim(DomainNames[Count]);
8601 ++Count;
8602 }
8603
8604 fclose(fptr);
8605 }
8606
8607 if (Count == 0)
8608 {
8609 critical_alert("incremental", "%s", "ldap.incr cannot run due to a "
8610 "configuration error in ldap.cfg");
8611 return(1);
8612 }
8613
8614 return(0);
8615}
8616
8617int email_isvalid(const char *address) {
8618 int count = 0;
8619 const char *c, *domain;
8620 static char *rfc822_specials = "()<>@,;:\\\"[]";
8621
8622 if(address[strlen(address) - 1] == '.')
8623 return 0;
8624
8625 /* first we validate the name portion (name@domain) */
8626 for (c = address; *c; c++) {
8627 if (*c == '\"' && (c == address || *(c - 1) == '.' || *(c - 1) ==
8628 '\"')) {
8629 while (*++c) {
8630 if (*c == '\"')
8631 break;
8632 if (*c == '\\' && (*++c == ' '))
8633 continue;
8634 if (*c <= ' ' || *c >= 127)
8635 return 0;
8636 }
8637
8638 if (!*c++)
8639 return 0;
8640 if (*c == '@')
8641 break;
8642 if (*c != '.')
8643 return 0;
8644 continue;
8645 }
8646
8647 if (*c == '@')
8648 break;
8649 if (*c <= ' ' || *c >= 127)
8650 return 0;
8651 if (strchr(rfc822_specials, *c))
8652 return 0;
8653 }
8654
8655 if (c == address || *(c - 1) == '.')
8656 return 0;
8657
8658 /* next we validate the domain portion (name@domain) */
8659 if (!*(domain = ++c)) return 0;
8660 do {
8661 if (*c == '.') {
8662 if (c == domain || *(c - 1) == '.')
8663 return 0;
8664 count++;
8665 }
8666 if (*c <= ' ' || *c >= 127)
8667 return 0;
8668 if (strchr(rfc822_specials, *c))
8669 return 0;
8670 } while (*++c);
8671
8672 return (count >= 1);
8673}
8674
8675int find_homeMDB(LDAP *ldap_handle, char *dn_path, char **homeMDB,
8676 char **homeServerName)
8677{
8678 LK_ENTRY *group_base;
8679 LK_ENTRY *sub_group_base;
8680 LK_ENTRY *gPtr;
8681 LK_ENTRY *sub_gPtr;
8682 int group_count;
8683 int sub_group_count;
8684 char filter[1024];
8685 char sub_filter[1024];
8686 char search_path[1024];
8687 char range[1024];
8688 char *attr_array[3];
8689 char *s;
8690 int homeMDB_count = -1;
8691 int rc;
8692 int i;
8693 int mdbbl_count;
8694 int rangeStep = 1500;
8695 int rangeLow = 0;
8696 int rangeHigh = rangeLow + (rangeStep - 1);
8697 int isLast = 0;
8698
8699 /* Grumble..... microsoft not making it searchable from the root *grr* */
8700
8701 memset(filter, '\0', sizeof(filter));
8702 memset(search_path, '\0', sizeof(search_path));
8703
8704 sprintf(filter, "(objectClass=msExchMDB)");
8705 sprintf(search_path, "CN=Configuration,%s", dn_path);
8706 attr_array[0] = "distinguishedName";
8707 attr_array[1] = NULL;
8708
8709 group_base = NULL;
8710 group_count = 0;
8711
8712 if ((rc = linklist_build(ldap_handle, search_path, filter, attr_array,
8713 &group_base, &group_count,
8714 LDAP_SCOPE_SUBTREE)) != 0)
8715 {
8716 com_err(whoami, 0, "Unable to find msExchMDB %s",
8717 ldap_err2string(rc));
8718 return(rc);
8719 }
8720
8721 if (group_count)
8722 {
8723 gPtr = group_base;
8724
8725 while(gPtr) {
8726 if (((s = strstr(gPtr->dn, "Public")) != (char *) NULL) ||
8727 ((s = strstr(gPtr->dn, "Recover")) != (char *) NULL) ||
8728 ((s = strstr(gPtr->dn, "Reserve")) != (char *) NULL))
8729 {
8730 gPtr = gPtr->next;
8731 continue;
8732 }
8733
8734 /*
8735 * Due to limits in active directory we need to use the LDAP
8736 * range semantics to query and return all the values in
8737 * large lists, we will stop increasing the range when
8738 * the result count is 0.
8739 */
8740
8741 i = 0;
8742 mdbbl_count = 0;
8743
8744 for(;;)
8745 {
8746 memset(sub_filter, '\0', sizeof(sub_filter));
8747 memset(range, '\0', sizeof(range));
8748 sprintf(sub_filter, "(objectClass=msExchMDB)");
8749
8750 if(isLast)
8751 sprintf(range, "homeMDBBL;Range=%d-*", rangeLow);
8752 else
8753 sprintf(range, "homeMDBBL;Range=%d-%d", rangeLow, rangeHigh);
8754
8755 attr_array[0] = range;
8756 attr_array[1] = NULL;
8757
8758 sub_group_base = NULL;
8759 sub_group_count = 0;
8760
8761 if ((rc = linklist_build(ldap_handle, gPtr->dn, sub_filter,
8762 attr_array, &sub_group_base,
8763 &sub_group_count,
8764 LDAP_SCOPE_SUBTREE)) != 0)
8765 {
8766 com_err(whoami, 0, "Unable to find homeMDBBL %s",
8767 ldap_err2string(rc));
8768 return(rc);
8769 }
8770
8771 if(!sub_group_count)
8772 {
8773 if(isLast)
8774 {
8775 isLast = 0;
8776 rangeLow = 0;
8777 rangeHigh = rangeLow + (rangeStep - 1);
8778 break;
8779 }
8780 else
8781 isLast++;
8782 }
8783
8784 mdbbl_count += sub_group_count;
8785 rangeLow = rangeHigh + 1;
8786 rangeHigh = rangeLow + (rangeStep - 1);
8787 }
8788
8789 /* First time through, need to initialize or update the least used */
8790
8791 com_err(whoami, 0, "Mail store %s, count %d", gPtr->dn,
8792 mdbbl_count);
8793
8794 if(mdbbl_count < homeMDB_count || homeMDB_count == -1)
8795 {
8796 homeMDB_count = mdbbl_count;
8797 *homeMDB = strdup(gPtr->dn);
8798 }
8799
8800 gPtr = gPtr->next;
8801 linklist_free(sub_group_base);
8802 }
8803 }
8804
8805 linklist_free(group_base);
8806
8807 /*
8808 * Ok found the server least allocated need to now query to get its
8809 * msExchHomeServerName so we can set it as a user attribute
8810 */
8811
8812 attr_array[0] = "legacyExchangeDN";
8813 attr_array[1] = NULL;
8814
8815 group_count = 0;
8816 group_base = NULL;
8817
8818 if ((rc = linklist_build(ldap_handle, *homeMDB, filter,
8819 attr_array, &group_base,
8820 &group_count,
8821 LDAP_SCOPE_SUBTREE)) != 0)
8822 {
8823 com_err(whoami, 0, "Unable to find msExchHomeServerName %s",
8824 ldap_err2string(rc));
8825 return(rc);
8826 }
8827
8828 if(group_count)
8829 {
8830 *homeServerName = strdup(group_base->value);
8831 if((s = strrchr(*homeServerName, '/')) != (char *) NULL)
8832 {
8833 *s = '\0';
8834 }
8835 }
8836
8837 linklist_free(group_base);
8838
8839 return(rc);
8840}
8841
8842char *lowercase(char *s)
8843{
8844 char *p;
8845
8846 for (p = s; *p; p++)
8847 {
8848 if (isupper(*p))
8849 *p = tolower(*p);
8850 }
8851 return s;
8852}
8853
8854char *uppercase(char *s)
8855{
8856 char *p;
8857
8858 for (p = s; *p; p++)
8859 {
8860 if (islower(*p))
8861 *p = toupper(*p);
8862 }
8863 return s;
8864}
8865
8866char *escape_string(char *s)
8867{
8868 char *p, *q;
8869 char string[1024];
8870 char temp[1024];
8871 int i = 0;
8872 int spaces = 0;
8873
8874 memset(string, '\0', sizeof(string));
8875
8876 q = s;
8877
8878 /* Replace leading spaces */
8879
8880 while(isspace(*q)) {
8881 string[i++] = '\\';
8882 string[i++] = '2';
8883 string[i++] = '0';
8884 q++;
8885 }
8886
8887 /* Escape any special characters */
8888
8889 for(; *q != '\0'; q++) {
8890 if(*q == ',')
8891 string[i++] = '\\';
8892 if(*q == '+')
8893 string[i++] = '\\';
8894 if(*q == '"')
8895 string[i++] = '\\';
8896 if(*q == '\\')
8897 string[i++] = '\\';
8898 if(*q == '<')
8899 string[i++] = '\\';
8900 if(*q == '>')
8901 string[i++] = '\\';
8902 if(*q == ';')
8903 string[i++] = '\\';
8904 if(*q == '#')
8905 string[i++] = '\\';
8906 if(*q == '=')
8907 string[i++] = '\\';
8908
8909 string[i++] = *q;
8910 }
8911
8912 return strdup(string);
8913}
8914
8915int save_query_info(int argc, char **argv, void *hint)
8916{
8917 int i;
8918 char **nargv = hint;
8919
8920 for(i = 0; i < argc; i++)
8921 nargv[i] = strdup(argv[i]);
8922
8923 return MR_CONT;
8924}
This page took 1.205395 seconds and 5 git commands to generate.