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