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