]> andersk Git - moira.git/blame - incremental/ldap/winad.c
Distinguish list not existing from other error cases.
[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};
2412 u_int groupTypeControl;
2413 char groupTypeControlStr[80];
2414 char contact_mail[256];
2415 int n;
2416 int i;
2417 int rc;
2418 LK_ENTRY *group_base;
2419 int group_count;
2420 int MailDisabled = 0;
2421
2422 if(UseGroupUniversal)
2423 groupTypeControl = ADS_GROUP_TYPE_UNIVERSAL_GROUP;
2424 else
2425 groupTypeControl = ADS_GROUP_TYPE_GLOBAL_GROUP;
2426
2427 if (!check_string(before_group_name))
2428 {
2429 com_err(whoami, 0,
2430 "Unable to process invalid LDAP list name %s",
2431 before_group_name);
2432 return(AD_INVALID_NAME);
2433 }
2434
2435 if (!check_string(after_group_name))
2436 {
2437 com_err(whoami, 0,
2438 "Unable to process invalid LDAP list name %s", after_group_name);
2439 return(AD_INVALID_NAME);
2440 }
2441
2442 if (Exchange)
2443 {
2444 if(atoi(maillist))
2445 {
2446 group_count = 0;
2447 group_base = NULL;
2448
2449 sprintf(filter, "(&(objectClass=user)(cn=%s))", after_group_name);
2450 attr_array[0] = "cn";
2451 attr_array[1] = NULL;
2452
2453 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
2454 &group_base, &group_count,
2455 LDAP_SCOPE_SUBTREE)) != 0)
2456 {
2457 com_err(whoami, 0, "Unable to process group %s : %s",
2458 after_group_name, ldap_err2string(rc));
2459 return(rc);
2460 }
2461
2462 if (group_count)
2463 {
2464 com_err(whoami, 0, "Object already exists with name %s",
2465 after_group_name);
2466 MailDisabled++;
2467 }
2468
2469 linklist_free(group_base);
2470 group_base = NULL;
2471 group_count = 0;
2472 }
2473 }
2474
2475 group_count = 0;
2476 group_base = NULL;
2477
2478 if (rc = ad_get_group(ldap_handle, dn_path, before_group_name,
2479 before_group_membership,
2480 MoiraId, "samAccountName", &group_base,
2481 &group_count, filter))
2482 return(rc);
2483
2484 if (group_count == 0)
2485 {
2486 return(AD_NO_GROUPS_FOUND);
2487 }
2488
2489 if (group_count != 1)
2490 {
2491 com_err(whoami, 0, "Unable to process multiple groups with "
c9ef9269 2492 "MoiraId = %s exist in the directory", MoiraId);
61a2844b 2493 return(AD_MULTIPLE_GROUPS_FOUND);
2494 }
2495
2496 strcpy(old_dn, group_base->dn);
2497
2498 linklist_free(group_base);
2499 group_base = NULL;
2500 group_count = 0;
2501 attr_array[0] = "sAMAccountName";
2502 attr_array[1] = NULL;
2503
2504 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
2505 &group_base, &group_count,
2506 LDAP_SCOPE_SUBTREE)) != 0)
2507 {
2508 com_err(whoami, 0, "Unable to get list %s dn : %s",
2509 after_group_name, ldap_err2string(rc));
2510 return(rc);
2511 }
2512
2513 if (group_count != 1)
2514 {
2515 com_err(whoami, 0,
2516 "Unable to get sAMAccountName for group %s",
2517 before_group_name);
2518 return(AD_LDAP_FAILURE);
2519 }
2520
2521 strcpy(sam_name, group_base->value);
2522 linklist_free(group_base);
2523 group_base = NULL;
2524 group_count = 0;
2525
2526 sprintf(new_dn_path, "%s,%s", after_group_ou, dn_path);
2527 sprintf(new_dn, "cn=%s", after_group_name);
2528 sprintf(mail, "%s@%s", after_group_name, lowercase(ldap_domain));
2529 sprintf(contact_mail, "%s@mit.edu", after_group_name);
2530 sprintf(proxy_address, "SMTP:%s@%s", after_group_name,
2531 lowercase(ldap_domain));
2532 sprintf(mail_nickname, "%s", after_group_name);
2533
2534 com_err(whoami, 0, "Old %s New %s,%s", old_dn, new_dn, new_dn_path);
2535
2536 if ((rc = ldap_rename_s(ldap_handle, old_dn, new_dn, new_dn_path,
2537 TRUE, NULL, NULL)) != LDAP_SUCCESS)
2538 {
2539 com_err(whoami, 0, "Unable to rename list from %s to %s : %s",
2540 before_group_name, after_group_name, ldap_err2string(rc));
2541 return(rc);
2542 }
2543
2544 name_v[0] = after_group_name;
2545
2546 if (!strncmp(&sam_name[strlen(sam_name) - strlen(group_suffix)],
2547 group_suffix, strlen(group_suffix)))
2548 {
2549 sprintf(sam_name, "%s%s", after_group_name, group_suffix);
2550 }
2551 else
2552 {
2553 com_err(whoami, 0,
2554 "Unable to rename list from %s to %s : sAMAccountName not found",
2555 before_group_name, after_group_name);
2556 return(rc);
2557 }
2558
2559 samAccountName_v[0] = sam_name;
2560
2561 if (after_security_flag)
2562 groupTypeControl |= ADS_GROUP_TYPE_SECURITY_ENABLED;
2563
2564 sprintf(groupTypeControlStr, "%ld", groupTypeControl);
2565 groupTypeControl_v[0] = groupTypeControlStr;
2566 mitMoiraId_v[0] = MoiraId;
2567
2568 sprintf(new_dn, "cn=%s,%s,%s", after_group_name, after_group_ou, dn_path);
2569 rc = attribute_update(ldap_handle, new_dn, after_desc, "description",
2570 after_group_name);
2571 n = 0;
2572 ADD_ATTR("samAccountName", samAccountName_v, LDAP_MOD_REPLACE);
2573 ADD_ATTR("displayName", name_v, LDAP_MOD_REPLACE);
2574 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_REPLACE);
2575 ADD_ATTR("groupType", groupTypeControl_v, LDAP_MOD_REPLACE);
2576
2577 if (Exchange)
2578 {
2579 if(atoi(maillist) && !MailDisabled && email_isvalid(mail))
2580 {
2581 mail_nickname_v[0] = mail_nickname;
2582 proxy_address_v[0] = proxy_address;
2583 mail_v[0] = mail;
2584 report_to_originator_v[0] = "TRUE";
2585
2586 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
2587 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2588 ADD_ATTR("proxyAddresses", proxy_address_v, LDAP_MOD_REPLACE);
2589 ADD_ATTR("reportToOriginator", report_to_originator_v,
2590 LDAP_MOD_REPLACE);
2591 }
2592 else
2593 {
2594 mail_nickname_v[0] = NULL;
2595 proxy_address_v[0] = NULL;
2596 mail_v[0] = NULL;
2597 legacy_exchange_dn_v[0] = NULL;
2598 address_book_v[0] = NULL;
2599 report_to_originator_v[0] = NULL;
2600
2601 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
2602 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2603 ADD_ATTR("proxyAddresses", proxy_address_v, LDAP_MOD_REPLACE);
2604 ADD_ATTR("legacyExchangeDN", legacy_exchange_dn_v, LDAP_MOD_REPLACE);
2605 ADD_ATTR("showInAddressBook", address_book_v, LDAP_MOD_REPLACE);
2606 ADD_ATTR("reportToOriginator", report_to_originator_v,
2607 LDAP_MOD_REPLACE);
2608 }
2609 }
2610 else
2611 {
2612 if(atoi(maillist) && email_isvalid(contact_mail))
2613 {
2614 mail_v[0] = contact_mail;
2615 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2616 }
2617 }
2618
2619 mods[n] = NULL;
2620
2621 if ((rc = ldap_modify_s(ldap_handle, new_dn, mods)) != LDAP_SUCCESS)
2622 {
2623 com_err(whoami, 0,
2624 "Unable to modify list data for %s after renaming: %s",
2625 after_group_name, ldap_err2string(rc));
2626 }
2627
2628 for (i = 0; i < n; i++)
2629 free(mods[i]);
2630
2631 return(rc);
2632}
2633
2634int group_create(int ac, char **av, void *ptr)
2635{
2636 LDAPMod *mods[20];
2637 char new_dn[256];
2638 char group_ou[256];
2639 char new_group_name[256];
2640 char sam_group_name[256];
2641 char cn_group_name[256];
2642 char mail[256];
2643 char contact_mail[256];
2644 char mail_nickname[256];
2645 char proxy_address[256];
2646 char address_book[256];
2647 char *cn_v[] = {NULL, NULL};
2648 char *objectClass_v[] = {"top", "group", NULL};
2649 char *objectClass_ldap_v[] = {"top", "microsoftComTop", "securityPrincipal",
2650 "group", "mailRecipient", NULL};
2651 char info[256];
2652 char *samAccountName_v[] = {NULL, NULL};
2653 char *altSecurityIdentities_v[] = {NULL, NULL};
2654 char *member_v[] = {NULL, NULL};
2655 char *name_v[] = {NULL, NULL};
2656 char *desc_v[] = {NULL, NULL};
2657 char *info_v[] = {NULL, NULL};
2658 char *mitMoiraId_v[] = {NULL, NULL};
2659 char *mitMoiraPublic_v[] = {NULL, NULL};
2660 char *mitMoiraHidden_v[] = {NULL, NULL};
2661 char *groupTypeControl_v[] = {NULL, NULL};
2662 char *mail_v[] = {NULL, NULL};
2663 char *proxy_address_v[] = {NULL, NULL};
2664 char *mail_nickname_v[] = {NULL, NULL};
2665 char *report_to_originator_v[] = {NULL, NULL};
2666 char *address_book_v[] = {NULL, NULL};
2667 char *legacy_exchange_dn_v[] = {NULL, NULL};
2668 char *gidNumber_v[] = {NULL, NULL};
2669 char groupTypeControlStr[80];
2670 char group_membership[1];
2671 int i;
2672 int security_flag;
2673 u_int groupTypeControl;
2674 int n;
2675 int rc;
2676 int updateGroup;
2677 int MailDisabled = 0;
2678 char **call_args;
2679 LK_ENTRY *group_base;
2680 int group_count;
2681 char filter[1024];
2682 char *attr_array[3];
2683
2684 call_args = ptr;
2685
2686 if(UseGroupUniversal)
2687 groupTypeControl = ADS_GROUP_TYPE_UNIVERSAL_GROUP;
2688 else
2689 groupTypeControl = ADS_GROUP_TYPE_GLOBAL_GROUP;
2690
2691 if (!check_string(av[L_NAME]))
2692 {
2693 com_err(whoami, 0, "Unable to process invalid LDAP list name %s",
2694 av[L_NAME]);
2695 return(AD_INVALID_NAME);
2696 }
2697
2698 updateGroup = (int)call_args[4];
2699 memset(group_ou, 0, sizeof(group_ou));
2700 memset(group_membership, 0, sizeof(group_membership));
2701 security_flag = 0;
2702
2703 get_group_membership(group_membership, group_ou, &security_flag, av);
2704
2705 strcpy(new_group_name, av[L_NAME]);
2706 sprintf(new_dn, "cn=%s,%s,%s", new_group_name, group_ou, call_args[1]);
2707 sprintf(contact_mail, "%s@mit.edu", av[L_NAME]);
2708 sprintf(mail, "%s@%s", av[L_NAME], lowercase(ldap_domain));
2709 sprintf(mail_nickname, "%s", av[L_NAME]);
2710
2711 if (security_flag)
2712 groupTypeControl |= ADS_GROUP_TYPE_SECURITY_ENABLED;
2713
2714 sprintf(sam_group_name, "%s%s", av[L_NAME], group_suffix);
2715
2716 if (!updateGroup)
2717 {
2718 sprintf(groupTypeControlStr, "%ld", groupTypeControl);
2719 groupTypeControl_v[0] = groupTypeControlStr;
2720
2721 strcpy(cn_group_name, av[L_NAME]);
2722
2723 samAccountName_v[0] = sam_group_name;
2724 name_v[0] = new_group_name;
2725 cn_v[0] = new_group_name;
2726
2727 n = 0;
2728 ADD_ATTR("cn", cn_v, LDAP_MOD_ADD);
2729
2730 if(ActiveDirectory)
2731 {
2732 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
2733 }
2734 else
2735 {
2736 mitMoiraPublic_v[0] = av[L_PUBLIC];
2737 mitMoiraHidden_v[0] = av[L_HIDDEN];
2738 ADD_ATTR("objectClass", objectClass_ldap_v, LDAP_MOD_ADD);
2739 ADD_ATTR("mitMoiraPublic", mitMoiraPublic_v, LDAP_MOD_ADD);
2740 ADD_ATTR("mitMoiraHidden", mitMoiraHidden_v, LDAP_MOD_ADD);
2741
2742 if(atoi(av[L_GROUP]))
2743 {
2744 gidNumber_v[0] = av[L_GID];
2745 ADD_ATTR("gidNumber", gidNumber_v, LDAP_MOD_ADD);
2746 }
2747 }
2748
2749 ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_ADD);
2750 ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
2751 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
2752
2753 if (Exchange)
2754 {
2755 if(atoi(av[L_MAILLIST]))
2756 {
2757 group_count = 0;
2758 group_base = NULL;
2759
2760 sprintf(filter, "(&(objectClass=user)(cn=%s))", av[L_NAME]);
2761 attr_array[0] = "cn";
2762 attr_array[1] = NULL;
2763
2764 if ((rc = linklist_build((LDAP *)call_args[0], call_args[1],
2765 filter, attr_array, &group_base,
2766 &group_count,
2767 LDAP_SCOPE_SUBTREE)) != 0)
2768 {
2769 com_err(whoami, 0, "Unable to process group %s : %s",
2770 av[L_NAME], ldap_err2string(rc));
2771 return(rc);
2772 }
2773
2774 if (group_count)
2775 {
2776 com_err(whoami, 0, "Object already exists with name %s",
2777 av[L_NAME]);
2778 MailDisabled++;
2779 }
2780
2781 linklist_free(group_base);
2782 group_base = NULL;
2783 group_count = 0;
2784 }
2785
2786 if(atoi(av[L_MAILLIST]) && !MailDisabled && email_isvalid(mail))
2787 {
2788 mail_nickname_v[0] = mail_nickname;
2789 report_to_originator_v[0] = "TRUE";
2790
2791 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_ADD);
2792 ADD_ATTR("reportToOriginator", report_to_originator_v,
2793 LDAP_MOD_ADD);
2794 }
2795 }
2796 else
2797 {
2798 if(atoi(av[L_MAILLIST]) && email_isvalid(contact_mail))
2799 {
2800 mail_v[0] = contact_mail;
2801 ADD_ATTR("mail", mail_v, LDAP_MOD_ADD);
2802 }
2803 }
2804
2805 if (strlen(av[L_DESC]) != 0)
2806 {
2807 desc_v[0] = av[L_DESC];
2808 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
2809 }
2810
2811 ADD_ATTR("groupType", groupTypeControl_v, LDAP_MOD_ADD);
2812
2813 if (strlen(av[L_ACE_NAME]) != 0)
2814 {
2815 sprintf(info, "The Administrator of this list is: %s",
2816 av[L_ACE_NAME]);
2817 info_v[0] = info;
2818 ADD_ATTR("info", info_v, LDAP_MOD_ADD);
2819 }
2820
2821 if (strlen(call_args[5]) != 0)
2822 {
2823 mitMoiraId_v[0] = call_args[5];
2824 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_ADD);
2825 }
2826
2827 mods[n] = NULL;
2828
2829 rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL);
2830
2831 for (i = 0; i < n; i++)
2832 free(mods[i]);
2833
2834 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
2835 {
c9ef9269 2836 com_err(whoami, 0, "Unable to create list %s in directory : %s",
61a2844b 2837 av[L_NAME], ldap_err2string(rc));
2838 callback_rc = rc;
2839 return(rc);
2840 }
2841 }
2842
2843 if ((rc == LDAP_ALREADY_EXISTS) || (updateGroup))
2844 {
2845 rc = attribute_update((LDAP *)call_args[0], new_dn, av[L_DESC],
2846 "description", av[L_NAME]);
2847 sprintf(info, "The Administrator of this list is: %s", av[L_ACE_NAME]);
2848
2849 rc = attribute_update((LDAP *)call_args[0], new_dn, info, "info",
2850 av[L_NAME]);
2851
2852 n = 0;
2853
2854 if (strlen(call_args[5]) != 0)
2855 {
2856 mitMoiraId_v[0] = call_args[5];
2857 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_REPLACE);
2858 }
2859
2860 if (!(atoi(av[L_ACTIVE])))
2861 {
2862 member_v[0] = NULL;
2863 ADD_ATTR("member", member_v, LDAP_MOD_REPLACE);
2864 }
2865
2866 if (!ActiveDirectory)
2867 {
2868 mitMoiraPublic_v[0] = av[L_PUBLIC];
2869 mitMoiraHidden_v[0] = av[L_HIDDEN];
2870 ADD_ATTR("mitMoiraPublic", mitMoiraPublic_v, LDAP_MOD_REPLACE);
2871 ADD_ATTR("mitMoiraHidden", mitMoiraHidden_v, LDAP_MOD_REPLACE);
2872
2873 if(atoi(av[L_GROUP]))
2874 {
2875 gidNumber_v[0] = av[L_GID];
2876 ADD_ATTR("gidNumber", gidNumber_v, LDAP_MOD_REPLACE);
2877 }
2878 else
2879 {
2880 ADD_ATTR("gidNumber", gidNumber_v, LDAP_MOD_REPLACE);
2881 }
2882 }
2883
2884 if (Exchange)
2885 {
2886 if(atoi(av[L_MAILLIST]))
2887 {
2888 group_count = 0;
2889 group_base = NULL;
2890
2891 sprintf(filter, "(&(objectClass=user)(cn=%s))", av[L_NAME]);
2892 attr_array[0] = "cn";
2893 attr_array[1] = NULL;
2894
2895 if ((rc = linklist_build((LDAP *)call_args[0], call_args[1],
2896 filter, attr_array, &group_base,
2897 &group_count,
2898 LDAP_SCOPE_SUBTREE)) != 0)
2899 {
2900 com_err(whoami, 0, "Unable to process group %s : %s",
2901 av[L_NAME], ldap_err2string(rc));
2902 return(rc);
2903 }
2904
2905 if (group_count)
2906 {
2907 com_err(whoami, 0, "Object already exists with name %s",
2908 av[L_NAME]);
2909 MailDisabled++;
2910 }
2911
2912 linklist_free(group_base);
2913 group_base = NULL;
2914 group_count = 0;
2915 }
2916
2917 if (atoi(av[L_MAILLIST]) && !MailDisabled && email_isvalid(mail))
2918 {
2919 mail_nickname_v[0] = mail_nickname;
2920 report_to_originator_v[0] = "TRUE";
2921
2922 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
2923 ADD_ATTR("reportToOriginator", report_to_originator_v,
2924 LDAP_MOD_REPLACE);
2925 }
2926 else
2927 {
2928 mail_v[0] = NULL;
2929 mail_nickname_v[0] = NULL;
2930 proxy_address_v[0] = NULL;
2931 legacy_exchange_dn_v[0] = NULL;
2932 address_book_v[0] = NULL;
2933 report_to_originator_v[0] = NULL;
2934
2935 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
2936 ADD_ATTR("proxyAddresses", proxy_address_v, LDAP_MOD_REPLACE);
2937 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2938 ADD_ATTR("legacyExchangeDN", legacy_exchange_dn_v,
2939 LDAP_MOD_REPLACE);
2940 ADD_ATTR("showInAddressBook", address_book_v, LDAP_MOD_REPLACE);
2941 ADD_ATTR("reportToOriginator", report_to_originator_v,
2942 LDAP_MOD_REPLACE);
2943 }
2944 }
2945 else
2946 {
2947 if (atoi(av[L_MAILLIST]) && email_isvalid(contact_mail))
2948 {
2949 mail_v[0] = contact_mail;
2950 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2951 }
2952 else
2953 {
2954 mail_v[0] = NULL;
2955 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2956 }
2957 }
2958
2959 mods[n] = NULL;
2960 rc = LDAP_SUCCESS;
2961
2962 if (n != 0)
2963 {
2964 rc = ldap_modify_s((LDAP *)call_args[0], new_dn, mods);
2965
2966 for (i = 0; i < n; i++)
2967 free(mods[i]);
2968
2969 if (rc != LDAP_SUCCESS)
2970 {
c9ef9269 2971 com_err(whoami, 0, "Unable to update list %s in directory : %s",
61a2844b 2972 av[L_NAME], ldap_err2string(rc));
2973 callback_rc = rc;
2974 return(rc);
2975 }
2976 }
2977 }
2978
2979 ProcessGroupSecurity((LDAP *)call_args[0], call_args[1], av[L_NAME],
2980 atoi(av[L_HIDDEN]), av[L_ACE_TYPE], av[L_ACE_NAME]);
2981
2982 return(LDAP_SUCCESS);
2983}
2984
2985int ProcessGroupSecurity(LDAP *ldap_handle, char *dn_path,
2986 char *TargetGroupName, int HiddenGroup,
2987 char *AceType, char *AceName)
2988{
2989 char filter_exp[1024];
2990 char *attr_array[5];
2991 char search_path[512];
2992 char root_ou[128];
2993 char TemplateDn[512];
2994 char TemplateSamName[128];
2995 char TargetDn[512];
2996 char TargetSamName[128];
2997 char AceSamAccountName[128];
2998 char AceDn[256];
2999 unsigned char AceSid[128];
3000 unsigned char UserTemplateSid[128];
3001 char acBERBuf[N_SD_BER_BYTES];
3002 char GroupSecurityTemplate[256];
3003 char hide_addres_lists[256];
3004 char address_book[256];
3005 char *hide_address_lists_v[] = {NULL, NULL};
3006 char *address_book_v[] = {NULL, NULL};
3007 char *owner_v[] = {NULL, NULL};
3008 int AceSidCount;
3009 int UserTemplateSidCount;
3010 int group_count;
3011 int n;
3012 int i;
3013 int rc;
3014 int nVal;
3015 ULONG dwInfo;
3016 int array_count = 0;
3017 LDAPMod *mods[20];
3018 LK_ENTRY *group_base;
3019 LDAP_BERVAL **ppsValues;
3020 LDAPControl sControl = {"1.2.840.113556.1.4.801",
3021 { N_SD_BER_BYTES, acBERBuf },
3022 TRUE
3023 };
3024 LDAPControl *apsServerControls[] = {&sControl, NULL};
3025 LDAPMessage *psMsg;
3026
3027 dwInfo = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
3028 DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION;
3029 BEREncodeSecurityBits(dwInfo, acBERBuf);
3030
3031 sprintf(search_path, "%s,%s", group_ou_root, dn_path);
3032 sprintf(filter_exp, "(sAMAccountName=%s%s)", TargetGroupName, group_suffix);
3033 attr_array[0] = "sAMAccountName";
3034 attr_array[1] = NULL;
3035 group_count = 0;
3036 group_base = NULL;
3037
3038 if ((rc = linklist_build(ldap_handle, search_path, filter_exp, attr_array,
3039 &group_base, &group_count,
3040 LDAP_SCOPE_SUBTREE) != 0))
3041 return(1);
3042
3043 if (group_count != 1)
3044 {
3045 linklist_free(group_base);
3046 return(1);
3047 }
3048
3049 strcpy(TargetDn, group_base->dn);
3050 strcpy(TargetSamName, group_base->value);
3051 linklist_free(group_base);
3052 group_base = NULL;
3053 group_count = 0;
3054
3055 UserTemplateSidCount = 0;
3056 memset(UserTemplateSid, '\0', sizeof(UserTemplateSid));
3057 memset(AceSamAccountName, '\0', sizeof(AceSamAccountName));
3058 memset(AceSid, '\0', sizeof(AceSid));
3059 AceSidCount = 0;
3060 group_base = NULL;
3061 group_count = 0;
3062
3063 if (strlen(AceName) != 0)
3064 {
3065 if (!strcmp(AceType, "LIST"))
3066 {
3067 sprintf(AceSamAccountName, "%s%s", AceName, group_suffix);
3068 strcpy(root_ou, group_ou_root);
3069 }
3070 else if (!strcmp(AceType, "USER"))
3071 {
3072 sprintf(AceSamAccountName, "%s", AceName);
3073 strcpy(root_ou, user_ou);
3074 }
3075
3076 if (ActiveDirectory)
3077 {
3078 if (strlen(AceSamAccountName) != 0)
3079 {
3080 sprintf(search_path, "%s", dn_path);
3081 sprintf(filter_exp, "(sAMAccountName=%s)", AceSamAccountName);
3082 attr_array[0] = "objectSid";
3083 attr_array[1] = NULL;
3084 group_count = 0;
3085 group_base = NULL;
3086
3087 if ((rc = linklist_build(ldap_handle, search_path, filter_exp,
3088 attr_array, &group_base, &group_count,
3089 LDAP_SCOPE_SUBTREE) != 0))
3090 return(1);
3091 if (group_count == 1)
3092 {
3093 strcpy(AceDn, group_base->dn);
3094 AceSidCount = group_base->length;
3095 memcpy(AceSid, group_base->value, AceSidCount);
3096 }
3097 linklist_free(group_base);
3098 group_base = NULL;
3099 group_count = 0;
3100 }
3101 }
3102 else
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] = "samAccountName";
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 }
3121 linklist_free(group_base);
3122 group_base = NULL;
3123 group_count = 0;
3124 }
3125 }
3126 }
3127
3128 if (!ActiveDirectory)
3129 {
3130 if (strlen(AceDn) != 0)
3131 {
3132 owner_v[0] = strdup(AceDn);
3133 n = 0;
3134 ADD_ATTR("owner", owner_v, LDAP_MOD_REPLACE);
3135
3136 mods[n] = NULL;
3137
3138 rc = ldap_modify_s(ldap_handle, TargetDn, mods);
3139
3140 for (i = 0; i < n; i++)
3141 free(mods[i]);
3142
3143 if (rc != LDAP_SUCCESS)
3144 com_err(whoami, 0, "Unable to set owner for group %s : %s",
3145 TargetGroupName, ldap_err2string(rc));
3146 }
3147
3148 return(rc);
3149 }
3150
3151 if (AceSidCount == 0)
3152 {
3153 com_err(whoami, 0, "Group %s: Administrator: %s, Type: %s - does not "
c9ef9269 3154 "have a directory SID.", TargetGroupName, AceName, AceType);
61a2844b 3155 com_err(whoami, 0, " Non-admin security group template will be used.");
3156 }
3157 else
3158 {
3159 sprintf(search_path, "%s,%s", security_template_ou, dn_path);
3160 sprintf(filter_exp, "(sAMAccountName=%s)", "UserTemplate.u");
3161 attr_array[0] = "objectSid";
3162 attr_array[1] = NULL;
3163
3164 group_count = 0;
3165 group_base = NULL;
3166
3167 if ((rc = linklist_build(ldap_handle, search_path, filter_exp,
3168 attr_array, &group_base, &group_count,
3169 LDAP_SCOPE_SUBTREE) != 0))
3170 return(1);
3171
3172 if ((rc != 0) || (group_count != 1))
3173 {
3174 com_err(whoami, 0, "Unable to process user security template: %s",
3175 "UserTemplate");
3176 AceSidCount = 0;
3177 }
3178 else
3179 {
3180 UserTemplateSidCount = group_base->length;
3181 memcpy(UserTemplateSid, group_base->value, UserTemplateSidCount);
3182 }
3183 linklist_free(group_base);
3184 group_base = NULL;
3185 group_count = 0;
3186 }
3187
3188 if (HiddenGroup)
3189 {
3190 if (AceSidCount == 0)
3191 {
3192 strcpy(GroupSecurityTemplate, HIDDEN_GROUP);
3193 sprintf(filter_exp, "(sAMAccountName=%s)", HIDDEN_GROUP);
3194 }
3195 else
3196 {
3197 strcpy(GroupSecurityTemplate, HIDDEN_GROUP_WITH_ADMIN);
3198 sprintf(filter_exp, "(sAMAccountName=%s)", HIDDEN_GROUP_WITH_ADMIN);
3199 }
3200 }
3201 else
3202 {
3203 if (AceSidCount == 0)
3204 {
3205 strcpy(GroupSecurityTemplate, NOT_HIDDEN_GROUP);
3206 sprintf(filter_exp, "(sAMAccountName=%s)", NOT_HIDDEN_GROUP);
3207 }
3208 else
3209 {
3210 strcpy(GroupSecurityTemplate, NOT_HIDDEN_GROUP_WITH_ADMIN);
3211 sprintf(filter_exp, "(sAMAccountName=%s)",
3212 NOT_HIDDEN_GROUP_WITH_ADMIN);
3213 }
3214 }
3215
3216 sprintf(search_path, "%s,%s", security_template_ou, dn_path);
3217 attr_array[0] = "sAMAccountName";
3218 attr_array[1] = NULL;
3219 group_count = 0;
3220 group_base = NULL;
3221
3222 if ((rc = linklist_build(ldap_handle, search_path, filter_exp, attr_array,
3223 &group_base, &group_count,
3224 LDAP_SCOPE_SUBTREE) != 0))
3225 return(1);
3226
3227 if (group_count != 1)
3228 {
3229 linklist_free(group_base);
3230 com_err(whoami, 0, "Unable to process group security template: %s - "
3231 "security not set", GroupSecurityTemplate);
3232 return(1);
3233 }
3234
3235 strcpy(TemplateDn, group_base->dn);
3236 strcpy(TemplateSamName, group_base->value);
3237 linklist_free(group_base);
3238 group_base = NULL;
3239 group_count = 0;
3240
3241 sprintf(filter_exp, "(sAMAccountName=%s)", TemplateSamName);
3242 rc = ldap_search_ext_s(ldap_handle,
3243 TemplateDn,
3244 LDAP_SCOPE_SUBTREE,
3245 filter_exp,
3246 NULL,
3247 0,
3248 apsServerControls,
3249 NULL,
3250 NULL,
3251 0,
3252 &psMsg);
3253
3254 if ((psMsg = ldap_first_entry(ldap_handle, psMsg)) == NULL)
3255 {
3256 com_err(whoami, 0, "Unable to find group security template: %s - "
3257 "security not set", GroupSecurityTemplate);
3258 return(1);
3259 }
3260
3261 ppsValues = ldap_get_values_len(ldap_handle, psMsg, "ntSecurityDescriptor");
3262
3263 if (ppsValues == NULL)
3264 {
3265 com_err(whoami, 0, "Unable to find group security descriptor for group "
3266 "%s - security not set", GroupSecurityTemplate);
3267 return(1);
3268 }
3269
3270 if (AceSidCount != 0)
3271 {
3272 for (nVal = 0; ppsValues[nVal] != NULL; nVal++)
3273 {
3274 for (i = 0;
3275 i < (int)(ppsValues[nVal]->bv_len - UserTemplateSidCount); i++)
3276 {
3277 if (!memcmp(&ppsValues[nVal]->bv_val[i], UserTemplateSid,
3278 UserTemplateSidCount))
3279 {
3280 memcpy(&ppsValues[nVal]->bv_val[i], AceSid, AceSidCount);
3281 break;
3282 }
3283 }
3284 }
3285 }
3286
3287 n = 0;
3288 ADD_ATTR("ntSecurityDescriptor", (char **)ppsValues,
3289 LDAP_MOD_REPLACE | LDAP_MOD_BVALUES);
3290
3291 if (Exchange)
3292 {
3293 if(HiddenGroup)
3294 {
3295 hide_address_lists_v[0] = "TRUE";
3296 address_book_v[0] = NULL;
3297 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
3298 LDAP_MOD_REPLACE);
3299 ADD_ATTR("showInAddressBook", address_book_v, LDAP_MOD_REPLACE);
3300 } else {
3301 hide_address_lists_v[0] = NULL;
3302 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
3303 LDAP_MOD_REPLACE);
3304 }
3305 }
3306
3307 mods[n] = NULL;
3308
3309 rc = ldap_modify_s(ldap_handle, TargetDn, mods);
3310
3311 for (i = 0; i < n; i++)
3312 free(mods[i]);
3313
3314 ldap_value_free_len(ppsValues);
3315 ldap_msgfree(psMsg);
3316
3317 if (rc != LDAP_SUCCESS)
3318 {
3319 com_err(whoami, 0, "Unable to set security settings for group %s : %s",
3320 TargetGroupName, ldap_err2string(rc));
3321
3322 if (AceSidCount != 0)
3323 {
3324 com_err(whoami, 0,
3325 "Trying to set security for group %s without admin.",
3326 TargetGroupName);
3327
3328 if (rc = ProcessGroupSecurity(ldap_handle, dn_path, TargetGroupName,
3329 HiddenGroup, "", ""))
3330 {
3331 com_err(whoami, 0, "Unable to set security for group %s.",
3332 TargetGroupName);
3333 return(rc);
3334 }
3335 }
3336 return(rc);
3337 }
3338
3339 return(rc);
3340}
3341
3342int group_delete(LDAP *ldap_handle, char *dn_path, char *group_name,
3343 char *group_membership, char *MoiraId)
3344{
3345 LK_ENTRY *group_base;
3346 char temp[512];
3347 char filter[128];
3348 int group_count;
3349 int rc;
3350
3351 if (!check_string(group_name))
3352 {
3353 com_err(whoami, 0,
3354 "Unable to process invalid LDAP list name %s", group_name);
3355 return(AD_INVALID_NAME);
3356 }
3357
3358 memset(filter, '\0', sizeof(filter));
3359 group_count = 0;
3360 group_base = NULL;
3361 sprintf(temp, "%s,%s", group_ou_root, dn_path);
3362
3363 if (rc = ad_get_group(ldap_handle, temp, group_name,
3364 group_membership, MoiraId,
3365 "samAccountName", &group_base,
3366 &group_count, filter))
3367 return(rc);
3368
3369 if (group_count == 1)
3370 {
3371 if ((rc = ldap_delete_s(ldap_handle, group_base->dn)) != LDAP_SUCCESS)
3372 {
3373 linklist_free(group_base);
c9ef9269 3374 com_err(whoami, 0, "Unable to delete list %s from directory : %s",
61a2844b 3375 group_name, ldap_err2string(rc));
3376 return(rc);
3377 }
3378 linklist_free(group_base);
3379 }
3380 else
3381 {
3382 linklist_free(group_base);
c9ef9269 3383 com_err(whoami, 0, "Unable to find list %s in directory.", group_name);
61a2844b 3384 return(AD_NO_GROUPS_FOUND);
3385 }
3386
3387 return(0);
3388}
3389
3390int BEREncodeSecurityBits(ULONG uBits, char *pBuffer)
3391{
3392 *pBuffer++ = 0x30;
3393 *pBuffer++ = 0x03;
3394 *pBuffer++ = 0x02;
3395 *pBuffer++ = 0x00;
3396 return(N_SD_BER_BYTES);
3397}
3398
3399int process_lists(int ac, char **av, void *ptr)
3400{
3401 int rc;
3402 int security_flag;
3403 char group_ou[256];
3404 char group_membership[2];
3405 char **call_args;
3406
3407 call_args = ptr;
3408
3409 security_flag = 0;
3410 memset(group_ou, '\0', sizeof(group_ou));
3411 memset(group_membership, '\0', sizeof(group_membership));
3412 get_group_membership(group_membership, group_ou, &security_flag, av);
3413 rc = populate_group((LDAP *)call_args[0], (char *)call_args[1],
3414 av[L_NAME], group_ou, group_membership,
3415 security_flag, "");
3416
3417 return(0);
3418}
3419
3420int member_list_build(int ac, char **av, void *ptr)
3421{
3422 LK_ENTRY *linklist;
3423 char temp[1024];
3424 char **call_args;
3425 char *s;
3426 call_args = ptr;
0d2076dc 3427
61a2844b 3428 strcpy(temp, av[ACE_NAME]);
c9ef9269 3429 StringTrim(temp);
3430
61a2844b 3431 if (!check_string(temp))
3432 return(0);
3433
3434 if (!strcmp(av[ACE_TYPE], "USER"))
3435 {
3436 if (!((int)call_args[3] & MOIRA_USERS))
3437 return(0);
3438 }
3439 else if (!strcmp(av[ACE_TYPE], "STRING"))
3440 {
3441 if (Exchange)
3442 {
3443 if((s = strchr(temp, '@')) == (char *) NULL)
3444 {
3445 strcat(temp, "@mit.edu");
3446 }
3447
3448 if(!strncasecmp(&temp[strlen(temp) - 6], ".LOCAL", 6))
3449 {
3450 s = strrchr(temp, '.');
3451 *s = '\0';
3452 strcat(s, ".mit.edu");
3453 }
3454 }
0d2076dc 3455
61a2844b 3456 if (!((int)call_args[3] & MOIRA_STRINGS))
3457 return(0);
0d2076dc 3458
61a2844b 3459 if (contact_create((LDAP *)call_args[0], call_args[1], temp, contact_ou))
3460 return(0);
61a2844b 3461 }
3462 else if (!strcmp(av[ACE_TYPE], "LIST"))
3463 {
3464 if (!((int)call_args[3] & MOIRA_LISTS))
3465 return(0);
3466 }
3467 else if (!strcmp(av[ACE_TYPE], "KERBEROS"))
3468 {
3469 if (!((int)call_args[3] & MOIRA_KERBEROS))
3470 return(0);
3471
3472 if (contact_create((LDAP *)call_args[0], call_args[1], temp,
3473 kerberos_ou))
3474 return(0);
3475
3476 }
e8332ac3 3477 else if (!strcmp(av[ACE_TYPE], "MACHINE"))
3478 {
3479 if (!((int)call_args[3] & MOIRA_MACHINE))
3480 return(0);
3481 }
61a2844b 3482 else
3483 return(0);
3484
3485 linklist = member_base;
3486
3487 while (linklist)
3488 {
0d2076dc 3489 if (!strcasecmp(temp, linklist->member) &&
3490 !strcasecmp(av[ACE_TYPE], linklist->type))
61a2844b 3491 return(0);
3492
3493 linklist = linklist->next;
3494 }
3495
3496 linklist = calloc(1, sizeof(LK_ENTRY));
3497 linklist->op = 1;
3498 linklist->dn = NULL;
3499 linklist->list = calloc(1, strlen(call_args[2]) + 1);
3500 strcpy(linklist->list, call_args[2]);
3501 linklist->type = calloc(1, strlen(av[ACE_TYPE]) + 1);
3502 strcpy(linklist->type, av[ACE_TYPE]);
3503 linklist->member = calloc(1, strlen(temp) + 1);
3504 strcpy(linklist->member, temp);
3505 linklist->next = member_base;
3506 member_base = linklist;
3507
3508 return(0);
3509}
3510
3511int member_remove(LDAP *ldap_handle, char *dn_path, char *group_name,
3512 char *group_ou, char *group_membership, char *user_name,
3513 char *UserOu, char *MoiraId)
3514{
3515 char distinguished_name[1024];
3516 char *modvalues[2];
3517 char temp[256];
3518 char filter[128];
3519 char *attr_array[3];
3520 int group_count;
3521 int i;
3522 int n;
3523 LDAPMod *mods[20];
3524 LK_ENTRY *group_base;
3525 ULONG rc;
3526 char *s;
3527
3528 if (!check_string(group_name))
3529 return(AD_INVALID_NAME);
3530
3531 memset(filter, '\0', sizeof(filter));
3532 group_base = NULL;
3533 group_count = 0;
3534
3535 if (rc = ad_get_group(ldap_handle, dn_path, group_name,
3536 group_membership, MoiraId,
3537 "samAccountName", &group_base,
3538 &group_count, filter))
3539 return(rc);
3540
3541 if (group_count != 1)
3542 {
c9ef9269 3543 com_err(whoami, 0, "Unable to find list %s in directory",
61a2844b 3544 group_name);
3545 linklist_free(group_base);
3546 group_base = NULL;
3547 group_count = 0;
3548 goto cleanup;
3549 }
3550
3551 strcpy(distinguished_name, group_base->dn);
3552 linklist_free(group_base);
3553 group_base = NULL;
3554 group_count = 0;
3555
3556 if(ActiveDirectory)
3557 {
3558 sprintf(temp, "CN=%s,%s,%s", user_name, UserOu, dn_path);
3559 }
3560 else
3561 {
3562 if(!strcmp(UserOu, user_ou))
3563 sprintf(temp, "uid=%s,%s,%s", user_name, UserOu, dn_path);
3564 else
3565 sprintf(temp, "CN=%s,%s,%s", user_name, UserOu, dn_path);
3566 }
3567
3568 modvalues[0] = temp;
3569 modvalues[1] = NULL;
3570
3571 n = 0;
3572 ADD_ATTR("member", modvalues, LDAP_MOD_DELETE);
3573 mods[n] = NULL;
3574 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
3575
3576 for (i = 0; i < n; i++)
3577 free(mods[i]);
3578
3579 if (rc == LDAP_UNWILLING_TO_PERFORM)
3580 rc = LDAP_SUCCESS;
3581
3582 if (rc != LDAP_SUCCESS)
3583 {
3584 com_err(whoami, 0, "Unable to modify list %s members : %s",
3585 group_name, ldap_err2string(rc));
3586 goto cleanup;
3587 }
3588
3589 if ((!strcmp(UserOu, contact_ou)) || (!strcmp(UserOu, kerberos_ou)))
3590 {
3591 if (Exchange)
3592 {
3593 if(!strcmp(UserOu, contact_ou) &&
3594 ((s = strstr(user_name, "@mit.edu")) != (char *) NULL))
3595 {
3596 memset(temp, '\0', sizeof(temp));
3597 strcpy(temp, user_name);
3598 s = strchr(temp, '@');
3599 *s = '\0';
3600
3601 sprintf(filter, "(&(objectClass=user)(mailNickName=%s))", temp);
3602
3603 if ((rc = linklist_build(ldap_handle, dn_path, filter, NULL,
3604 &group_base, &group_count,
3605 LDAP_SCOPE_SUBTREE) != 0))
3606 return(rc);
3607
3608 if(group_count)
3609 goto cleanup;
3610
3611 linklist_free(group_base);
3612 group_base = NULL;
3613 group_count = 0;
3614 }
3615
3616 sprintf(filter, "(distinguishedName=%s)", temp);
3617 attr_array[0] = "memberOf";
3618 attr_array[1] = NULL;
3619
3620 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
3621 &group_base, &group_count,
3622 LDAP_SCOPE_SUBTREE) != 0))
3623 return(rc);
3624
3625
3626 if(!group_count)
3627 {
3628 com_err(whoami, 0, "Removing unreferenced object %s", temp);
3629
3630 if ((rc = ldap_delete_s(ldap_handle, temp)) != 0)
3631 return(rc);
3632 }
3633 }
3634 }
3635
3636 cleanup:
3637 return(rc);
3638}
3639
3640int member_add(LDAP *ldap_handle, char *dn_path, char *group_name,
3641 char *group_ou, char *group_membership, char *user_name,
3642 char *UserOu, char *MoiraId)
3643{
3644 char distinguished_name[1024];
3645 char *modvalues[2];
3646 char temp[256];
3647 char filter[128];
3648 int group_count;
3649 int n;
3650 int i;
3651 LDAPMod *mods[20];
3652 LK_ENTRY *group_base;
3653 ULONG rc;
3654
3655 if (!check_string(group_name))
3656 return(AD_INVALID_NAME);
3657
3658 rc = 0;
3659 memset(filter, '\0', sizeof(filter));
3660 group_base = NULL;
3661 group_count = 0;
3662
3663 if (rc = ad_get_group(ldap_handle, dn_path, group_name,
3664 group_membership, MoiraId,
3665 "samAccountName", &group_base,
3666 &group_count, filter))
3667 return(rc);
3668
3669 if (group_count != 1)
3670 {
3671 linklist_free(group_base);
3672 group_base = NULL;
3673 group_count = 0;
c9ef9269 3674 com_err(whoami, 0, "Unable to find list %s %d in directory",
61a2844b 3675 group_name, group_count);
3676 return(AD_MULTIPLE_GROUPS_FOUND);
3677 }
3678
3679 strcpy(distinguished_name, group_base->dn);
3680 linklist_free(group_base);
3681 group_base = NULL;
3682 group_count = 0;
3683
3684 if(ActiveDirectory)
3685 {
3686 sprintf(temp, "CN=%s,%s,%s", user_name, UserOu, dn_path);
3687 }
3688 else
3689 {
3690 if(!strcmp(UserOu, user_ou))
3691 sprintf(temp, "uid=%s,%s,%s", user_name, UserOu, dn_path);
3692 else
3693 sprintf(temp, "cn=%s,%s,%s", user_name, UserOu, dn_path);
3694 }
3695
3696 modvalues[0] = temp;
3697 modvalues[1] = NULL;
3698
3699 n = 0;
3700 ADD_ATTR("member", modvalues, LDAP_MOD_ADD);
3701 mods[n] = NULL;
3702 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
3703
3704 if (rc == LDAP_ALREADY_EXISTS || rc == LDAP_TYPE_OR_VALUE_EXISTS)
3705 rc = LDAP_SUCCESS;
3706
3707 if ((!strcmp(UserOu, contact_ou)) || (!strcmp(UserOu, kerberos_ou)))
3708 {
3709 if (rc == LDAP_UNWILLING_TO_PERFORM)
3710 rc = LDAP_SUCCESS;
3711 }
3712
3713 for (i = 0; i < n; i++)
3714 free(mods[i]);
3715
3716 if (rc != LDAP_SUCCESS)
3717 {
3718 com_err(whoami, 0, "Unable to add %s to list %s as a member : %s",
3719 user_name, group_name, ldap_err2string(rc));
3720 }
3721
3722 return(rc);
3723}
3724
3725int contact_remove_email(LDAP *ld, char *bind_path,
3726 LK_ENTRY **linklist_base, int linklist_current)
3727{
3728 LK_ENTRY *gPtr;
3729 int rc;
3730 char *mail_v[] = {NULL, NULL};
3731 LDAPMod *mods[20];
3732 int n;
3733 int i;
3734
3735 mail_v[0] = NULL;
3736
3737 n = 0;
3738 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
3739 ADD_ATTR("mailNickName", mail_v, LDAP_MOD_REPLACE);
3740 ADD_ATTR("proxyAddresses", mail_v, LDAP_MOD_REPLACE);
3741 ADD_ATTR("targetAddress", mail_v, LDAP_MOD_REPLACE);
3742 mods[n] = NULL;
3743
3744 gPtr = (*linklist_base);
3745
3746 while(gPtr) {
3747 rc = ldap_modify_s(ld, gPtr->dn, mods);
3748
3749 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
3750 {
c9ef9269 3751 com_err(whoami, 0, "Unable to modify contact %s in directory : %s",
61a2844b 3752 gPtr->dn, ldap_err2string(rc));
3753 return(rc);
3754 }
3755
3756 gPtr = gPtr->next;
3757 }
3758
3759 for (i = 0; i < n; i++)
3760 free(mods[i]);
3761
3762 return(rc);
3763}
3764
3765int contact_create(LDAP *ld, char *bind_path, char *user, char *group_ou)
3766{
3767 LDAPMod *mods[20];
3768 LK_ENTRY *group_base;
3769 int group_count;
3770 char new_dn[256];
3771 char cn_user_name[256];
3772 char contact_name[256];
3773 char mail_nickname[256];
3774 char proxy_address_internal[256];
3775 char proxy_address_external[256];
3776 char target_address[256];
3777 char internal_contact_name[256];
3778 char filter[128];
3779 char mail[256];
3780 char principal[256];
3781 char mit_address_book[256];
3782 char default_address_book[256];
3783 char contact_address_book[256];
3784 char uid[256];
3785 char *email_v[] = {NULL, NULL};
3786 char *cn_v[] = {NULL, NULL};
3787 char *contact_v[] = {NULL, NULL};
3788 char *uid_v[] = {NULL, NULL};
3789 char *mail_nickname_v[] = {NULL, NULL};
3790 char *proxy_address_internal_v[] = {NULL, NULL};
3791 char *proxy_address_external_v[] = {NULL, NULL};
3792 char *target_address_v[] = {NULL, NULL};
3793 char *mit_address_book_v[] = {NULL, NULL};
3794 char *default_address_book_v[] = {NULL, NULL};
3795 char *contact_address_book_v[] = {NULL, NULL};
3796 char *hide_address_lists_v[] = {NULL, NULL};
3797 char *attr_array[3];
3798 char *objectClass_v[] = {"top", "person",
3799 "organizationalPerson",
3800 "contact", NULL};
3801 char *objectClass_ldap_v[] = {"top", "person", "microsoftComTop",
3802 "inetOrgPerson", "organizationalPerson",
3803 "contact", "mailRecipient", "eduPerson",
3804 NULL};
3805 char *name_v[] = {NULL, NULL};
3806 char *desc_v[] = {NULL, NULL};
3807 char *s;
3808 int n;
3809 int rc;
3810 int i;
3811 char temp[256];
3812 char *c;
3813 char *mail_routing_v[] = {NULL, NULL};
3814 char *principal_v[] = {NULL, NULL};
3815
3816 if (!check_string(user))
3817 {
3818 com_err(whoami, 0, "Unable to process invalid LDAP name %s", user);
3819 return(AD_INVALID_NAME);
3820 }
3821
3822 strcpy(mail, user);
3823 strcpy(contact_name, mail);
3824 strcpy(internal_contact_name, mail);
3825
3826 if((s = strchr(internal_contact_name, '@')) != NULL) {
3827 *s = '?';
3828 }
3829
3830 sprintf(cn_user_name,"CN=%s,%s,%s", escape_string(contact_name), group_ou,
3831 bind_path);
3832
3833 sprintf(target_address, "SMTP:%s", contact_name);
3834 sprintf(proxy_address_external, "SMTP:%s", contact_name);
3835 sprintf(mail_nickname, "%s", internal_contact_name);
3836
3837 cn_v[0] = cn_user_name;
3838 contact_v[0] = contact_name;
3839 uid_v[0] = uid;
3840 name_v[0] = user;
3841 desc_v[0] = "Auto account created by Moira";
3842 email_v[0] = mail;
3843 proxy_address_internal_v[0] = proxy_address_internal;
3844 proxy_address_external_v[0] = proxy_address_external;
3845 mail_nickname_v[0] = mail_nickname;
3846 target_address_v[0] = target_address;
3847 mit_address_book_v[0] = mit_address_book;
3848 default_address_book_v[0] = default_address_book;
3849 contact_address_book_v[0] = contact_address_book;
3850 strcpy(new_dn, cn_user_name);
3851 n = 0;
3852
3853 ADD_ATTR("cn", contact_v, LDAP_MOD_ADD);
3854
3855 if(!ActiveDirectory)
3856 {
3857 if(!strcmp(group_ou, contact_ou))
3858 sprintf(uid, "%s%s", contact_name, "_strings");
3859
3860 if(!strcmp(group_ou, kerberos_ou))
3861 sprintf(uid, "%s%s", contact_name, "_kerberos");
3862
3863 uid_v[0] = uid;
3864
3865 ADD_ATTR("sn", contact_v, LDAP_MOD_ADD);
3866 ADD_ATTR("uid", uid_v, LDAP_MOD_ADD);
3867 }
3868
3869 if(ActiveDirectory)
3870 {
3871 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
3872 }
3873 else
3874 {
3875 ADD_ATTR("objectClass", objectClass_ldap_v, LDAP_MOD_ADD);
3876 }
3877
3878 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
3879 ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
3880 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
3881
3882 if (Exchange)
3883 {
3884 if (!strcmp(group_ou, contact_ou) && email_isvalid(mail))
3885 {
3886 group_count = 0;
3887 group_base = NULL;
3888
3889 sprintf(filter, "(&(objectClass=user)(cn=%s))", mail);
3890 attr_array[0] = "cn";
3891 attr_array[1] = NULL;
3892
3893 if ((rc = linklist_build(ld, bind_path, filter, attr_array,
3894 &group_base, &group_count,
3895 LDAP_SCOPE_SUBTREE)) != 0)
3896 {
3897 com_err(whoami, 0, "Unable to process contact %s : %s",
3898 user, ldap_err2string(rc));
3899 return(rc);
3900 }
3901
3902 if (group_count)
3903 {
3904 com_err(whoami, 0, "Object already exists with name %s",
3905 user);
3906 return(1);
3907 }
3908
3909 linklist_free(group_base);
3910 group_base = NULL;
3911 group_count = 0;
3912
3913 sprintf(filter, "(&(objectClass=group)(cn=%s))", mail);
3914 attr_array[0] = "cn";
3915 attr_array[1] = NULL;
3916
3917 if ((rc = linklist_build(ld, bind_path, filter, attr_array,
3918 &group_base, &group_count,
3919 LDAP_SCOPE_SUBTREE)) != 0)
3920 {
3921 com_err(whoami, 0, "Unable to process contact %s : %s",
3922 user, ldap_err2string(rc));
3923 return(rc);
3924 }
3925
3926 if (group_count)
3927 {
3928 com_err(whoami, 0, "Object already exists with name %s",
3929 user);
3930 return(1);
3931 }
3932
3933 linklist_free(group_base);
3934 group_count = 0;
3935 group_base = NULL;
3936
3937 sprintf(filter, "(&(objectClass=user)(mail=%s))", mail);
3938 attr_array[0] = "cn";
3939 attr_array[1] = NULL;
3940
3941 if ((rc = linklist_build(ld, bind_path, filter, attr_array,
3942 &group_base, &group_count,
3943 LDAP_SCOPE_SUBTREE)) != 0)
3944 {
3945 com_err(whoami, 0, "Unable to process contact %s : %s",
3946 user, ldap_err2string(rc));
3947 return(rc);
3948 }
3949
3950 if (group_count)
3951 {
3952 com_err(whoami, 0, "Object already exists with name %s",
3953 user);
3954 return(1);
3955 }
3956
3957 linklist_free(group_base);
3958 group_base = NULL;
3959 group_count = 0;
3960
3961 sprintf(filter, "(&(objectClass=group)(mail=%s))", mail);
3962 attr_array[0] = "cn";
3963 attr_array[1] = NULL;
3964
3965 if ((rc = linklist_build(ld, bind_path, filter, attr_array,
3966 &group_base, &group_count,
3967 LDAP_SCOPE_SUBTREE)) != 0)
3968 {
3969 com_err(whoami, 0, "Unable to process contact %s : %s",
3970 user, ldap_err2string(rc));
3971 return(rc);
3972 }
3973
3974 if (group_count)
3975 {
3976 com_err(whoami, 0, "Object already exists with name %s",
3977 user);
3978 return(1);
3979 }
3980
3981 linklist_free(group_base);
3982 group_base = NULL;
3983 group_count = 0;
3984
3985 ADD_ATTR("mail", email_v, LDAP_MOD_ADD);
3986 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_ADD);
3987 ADD_ATTR("proxyAddresses", proxy_address_external_v, LDAP_MOD_ADD);
3988 ADD_ATTR("targetAddress", target_address_v, LDAP_MOD_ADD);
3989
3990 hide_address_lists_v[0] = "TRUE";
3991 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
3992 LDAP_MOD_ADD);
3993 }
3994 }
3995
3996 if(!ActiveDirectory)
3997 {
3998 if((c = strchr(mail, '@')) == NULL)
3999 sprintf(temp, "%s@mit.edu", mail);
4000 else
4001 sprintf(temp, "%s", mail);
4002
4003 mail_routing_v[0] = temp;
4004 email_v[0] = temp;
4005 principal_v[0] = principal;
4006
4007 if(!strcmp(group_ou, contact_ou))
4008 {
4009 ADD_ATTR("mailRoutingAddress", mail_routing_v, LDAP_MOD_ADD);
61a2844b 4010 ADD_ATTR("eduPersonPrincipalName", mail_routing_v, LDAP_MOD_ADD);
4011 }
4012 }
4013
4014 mods[n] = NULL;
4015
4016 rc = ldap_add_ext_s(ld, new_dn, mods, NULL, NULL);
4017
4018 for (i = 0; i < n; i++)
4019 free(mods[i]);
4020
4021 if (Exchange)
4022 {
4023 if ((rc != LDAP_SUCCESS) && (rc == LDAP_ALREADY_EXISTS) &&
4024 !strcmp(group_ou, contact_ou) && email_isvalid(mail))
4025 {
4026 n = 0;
4027
4028 ADD_ATTR("mail", email_v, LDAP_MOD_REPLACE);
4029 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
4030 ADD_ATTR("proxyAddresses", proxy_address_external_v,
4031 LDAP_MOD_REPLACE);
4032 ADD_ATTR("targetAddress", target_address_v, LDAP_MOD_REPLACE);
4033
4034 hide_address_lists_v[0] = "TRUE";
4035 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
4036 LDAP_MOD_REPLACE);
4037
4038 mods[n] = NULL;
4039 rc = ldap_modify_s(ld, new_dn, mods);
4040
4041 if (rc)
4042 {
4043 com_err(whoami, 0, "Unable to update contact %s", mail);
4044 }
4045
4046 for (i = 0; i < n; i++)
4047 free(mods[i]);
4048 }
4049 }
4050
61a2844b 4051 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
4052 {
4053 com_err(whoami, 0, "Unable to create contact %s : %s",
4054 user, ldap_err2string(rc));
4055 return(rc);
4056 }
4057
4058 return(0);
4059}
4060
4061int user_update(LDAP *ldap_handle, char *dn_path, char *user_name,
4062 char *Uid, char *MitId, char *MoiraId, int State,
4063 char *WinHomeDir, char *WinProfileDir, char *first,
4064 char *middle, char *last, char *shell, char *class)
4065{
4066 LDAPMod *mods[20];
4067 LK_ENTRY *group_base;
4068 int group_count;
4069 char distinguished_name[512];
4070 char displayName[256];
4071 char *mitMoiraId_v[] = {NULL, NULL};
4072 char *mitMoiraClass_v[] = {NULL, NULL};
4073 char *mitMoiraStatus_v[] = {NULL, NULL};
4074 char *uid_v[] = {NULL, NULL};
4075 char *mitid_v[] = {NULL, NULL};
4076 char *homedir_v[] = {NULL, NULL};
4077 char *winProfile_v[] = {NULL, NULL};
4078 char *drives_v[] = {NULL, NULL};
4079 char *userAccountControl_v[] = {NULL, NULL};
4080 char *alt_recipient_v[] = {NULL, NULL};
4081 char *hide_address_lists_v[] = {NULL, NULL};
4082 char *mail_v[] = {NULL, NULL};
4083 char *gid_v[] = {NULL, NULL};
4084 char *loginshell_v[] = {NULL, NULL};
4085 char *principal_v[] = {NULL, NULL};
4086 char userAccountControlStr[80];
4087 int n;
4088 int rc;
4089 int i;
4090 int OldUseSFU30;
4091 u_int userAccountControl = UF_NORMAL_ACCOUNT | UF_DONT_EXPIRE_PASSWD |
4092 UF_PASSWD_CANT_CHANGE;
4093 char filter[128];
4094 char *attr_array[3];
4095 char temp[1024];
4096 char mail[256];
4097 char contact_mail[256];
4098 char filter_exp[1024];
4099 char search_path[512];
4100 char TemplateDn[512];
4101 char TemplateSamName[128];
4102 char alt_recipient[256];
4103 char principal[256];
4104 char status[256];
4105 char acBERBuf[N_SD_BER_BYTES];
4106 LDAPControl sControl = {"1.2.840.113556.1.4.801",
4107 { N_SD_BER_BYTES, acBERBuf },
4108 TRUE};
4109 LDAPControl *apsServerControls[] = {&sControl, NULL};
4110 LDAPMessage *psMsg;
4111 LDAP_BERVAL **ppsValues;
4112 ULONG dwInfo;
4113 char *argv[3];
4114 char *homeMDB;
4115 char *homeServerName;
4116 char *save_argv[7];
4117 char search_string[256];
4118 char *p, *q;
4119 char *mail_routing_v[] = {NULL, NULL};
4120 char *c;
4121
4122 dwInfo = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
4123 DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION;
4124 BEREncodeSecurityBits(dwInfo, acBERBuf);
4125
4126 if (!check_string(user_name))
4127 {
4128 com_err(whoami, 0, "Unable to process invalid LDAP user name %s",
4129 user_name);
4130 return(AD_INVALID_NAME);
4131 }
4132
4133 memset(contact_mail, '\0', sizeof(contact_mail));
4134 sprintf(contact_mail, "%s@mit.edu", user_name);
4135 memset(mail, '\0', sizeof(mail));
4136 sprintf(mail, "%s@%s", user_name, lowercase(ldap_domain));
4137 memset(alt_recipient, '\0', sizeof(alt_recipient));
4138 sprintf(alt_recipient, "cn=%s@mit.edu,%s,%s", user_name, contact_ou,
4139 dn_path);
4140 sprintf(search_string, "@%s", uppercase(ldap_domain));
4141
4142 if (Exchange)
4143 {
4144 if(contact_create(ldap_handle, dn_path, contact_mail, contact_ou))
4145 {
4146 com_err(whoami, 0, "Unable to create user contact %s", contact_mail);
4147 }
4148 }
4149
4150 group_count = 0;
4151 group_base = NULL;
4152
4153 memset(displayName, '\0', sizeof(displayName));
4154
4155 if (strlen(MoiraId) != 0)
4156 {
4157 if(ActiveDirectory)
4158 {
4159 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
4160 }
4161 else
4162 {
4163 sprintf(filter,
4164 "(&(objectClass=mitPerson)(mitMoiraId=%s))", MoiraId);
4165 }
4166
4167 attr_array[0] = "cn";
4168 attr_array[1] = NULL;
4169 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
4170 &group_base, &group_count,
4171 LDAP_SCOPE_SUBTREE)) != 0)
4172 {
4173 com_err(whoami, 0, "Unable to process user %s : %s",
4174 user_name, ldap_err2string(rc));
4175 return(rc);
4176 }
4177 }
4178
4179 if (group_count != 1)
4180 {
4181 linklist_free(group_base);
4182 group_base = NULL;
4183 group_count = 0;
4184 sprintf(filter, "(sAMAccountName=%s)", user_name);
4185 attr_array[0] = "cn";
4186 attr_array[1] = NULL;
4187 sprintf(temp, "%s,%s", user_ou, dn_path);
4188 if ((rc = linklist_build(ldap_handle, temp, filter, attr_array,
4189 &group_base, &group_count,
4190 LDAP_SCOPE_SUBTREE)) != 0)
4191 {
4192 com_err(whoami, 0, "Unable to process user %s : %s",
4193 user_name, ldap_err2string(rc));
4194 return(rc);
4195 }
4196 }
4197
4198 if (group_count != 1)
4199 {
c9ef9269 4200 com_err(whoami, 0, "Unable to find user %s in directory",
61a2844b 4201 user_name);
4202 linklist_free(group_base);
4203 return(AD_NO_USER_FOUND);
4204 }
4205
4206 strcpy(distinguished_name, group_base->dn);
4207
4208 linklist_free(group_base);
4209 group_count = 0;
4210
4211 if(!ActiveDirectory)
4212 {
4213 if (rc = moira_connect())
4214 {
c9ef9269 4215 critical_alert("Ldap incremental",
61a2844b 4216 "Error contacting Moira server : %s",
4217 error_message(rc));
4218 return;
4219 }
4220
4221 argv[0] = user_name;
4222
4223 if (!(rc = mr_query("get_pobox", 1, argv, save_query_info, save_argv)))
4224 {
4225 n = 0;
4226 ADD_ATTR("mailRoutingAddress", mail_routing_v, LDAP_MOD_REPLACE);
4227 mods[n] = NULL;
4228 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
4229
4230 if (rc == LDAP_ALREADY_EXISTS || rc == LDAP_TYPE_OR_VALUE_EXISTS)
4231 rc = LDAP_SUCCESS;
4232
4233 if(rc)
4234 com_err(whoami, 0,
4235 "Unable to set the mailRoutingAddress for %s : %s",
4236 user_name, ldap_err2string(rc));
4237
4238 p = strdup(save_argv[3]);
4239
4240 if((c = strchr(p, ',')) != NULL)
4241 {
4242 q = strtok(p, ",");
4243 StringTrim(q);
4244
4245 if ((c = strchr(q, '@')) == NULL)
4246 sprintf(temp, "%s@mit.edu", q);
4247 else
4248 sprintf(temp, "%s", q);
4249
4250 if(email_isvalid(temp) && State != US_DELETED)
4251 {
4252 mail_routing_v[0] = temp;
4253
4254 n = 0;
4255 ADD_ATTR("mailRoutingAddress", mail_routing_v, LDAP_MOD_ADD);
4256 mods[n] = NULL;
4257 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
4258
4259 if (rc == LDAP_ALREADY_EXISTS ||
4260 rc == LDAP_TYPE_OR_VALUE_EXISTS)
4261 rc = LDAP_SUCCESS;
4262
4263 if(rc)
4264 com_err(whoami, 0,
4265 "Unable to set the mailRoutingAddress for %s : %s",
4266 user_name, ldap_err2string(rc));
4267 }
4268
4269 while((q = strtok(NULL, ",")) != NULL) {
4270 StringTrim(q);
4271
4272 if((c = strchr(q, '@')) == NULL)
4273 sprintf(temp, "%s@mit.edu", q);
4274 else
4275 sprintf(temp, "%s", q);
4276
4277 if(email_isvalid(temp) && State != US_DELETED)
4278 {
4279 mail_routing_v[0] = temp;
4280
4281 n = 0;
4282 ADD_ATTR("mailRoutingAddress", mail_routing_v,
4283 LDAP_MOD_ADD);
4284 mods[n] = NULL;
4285 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
4286
4287 if (rc == LDAP_ALREADY_EXISTS ||
4288 rc == LDAP_TYPE_OR_VALUE_EXISTS)
4289 rc = LDAP_SUCCESS;
4290
4291 if(rc)
4292 com_err(whoami, 0,
4293 "Unable to set the mailRoutingAddress for "
4294 "%s : %s",
4295 user_name, ldap_err2string(rc));
4296 }
4297 }
4298 } else {
4299 StringTrim(p);
4300
4301 if((c = strchr(p, '@')) == NULL)
4302 sprintf(temp, "%s@mit.edu", p);
4303 else
4304 sprintf(temp, "%s", p);
4305
4306 if(email_isvalid(temp) && State != US_DELETED)
4307 {
4308 mail_routing_v[0] = temp;
4309
4310 n = 0;
4311 ADD_ATTR("mailRoutingAddress", mail_routing_v, LDAP_MOD_ADD);
4312 mods[n] = NULL;
4313 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
4314
4315 if (rc == LDAP_ALREADY_EXISTS ||
4316 rc == LDAP_TYPE_OR_VALUE_EXISTS)
4317 rc = LDAP_SUCCESS;
4318
4319 if(rc)
4320 com_err(whoami, 0,
4321 "Unable to set the mailRoutingAddress for %s : %s",
4322 user_name, ldap_err2string(rc));
4323 }
4324 }
4325 }
4326 moira_disconnect();
4327 }
4328
4329 if ((strlen(MitId) != 0) && (MitId[0] == '9'))
4330 rc = attribute_update(ldap_handle, distinguished_name, MitId,
4331 "employeeID", user_name);
4332 else
4333 rc = attribute_update(ldap_handle, distinguished_name, "none",
4334 "employeeID", user_name);
4335
4336 if(strlen(first)) {
4337 strcat(displayName, first);
4338 }
4339
4340 if(strlen(middle)) {
4341 if(strlen(first))
4342 strcat(displayName, " ");
4343
4344 strcat(displayName, middle);
4345 }
4346
4347 if(strlen(last)) {
4348 if(strlen(middle) || strlen(first))
4349 strcat(displayName, " ");
4350
4351 strcat(displayName, last);
4352 }
4353
4354 if(strlen(displayName))
4355 rc = attribute_update(ldap_handle, distinguished_name, displayName,
4356 "displayName", user_name);
4357 else
4358 rc = attribute_update(ldap_handle, distinguished_name, user_name,
4359 "displayName", user_name);
4360
4361 if(!ActiveDirectory)
4362 {
4363 if(strlen(displayName))
4364 rc = attribute_update(ldap_handle, distinguished_name, displayName,
4365 "cn", user_name);
4366 else
4367 rc = attribute_update(ldap_handle, distinguished_name, user_name,
4368 "cn", user_name);
4369 }
4370
4371 if(!ActiveDirectory)
4372 {
4373 rc = attribute_update(ldap_handle, distinguished_name, displayName,
4374 "eduPersonNickname", user_name);
4375 }
4376
4377 if(strlen(first))
4378 rc = attribute_update(ldap_handle, distinguished_name, first,
4379 "givenName", user_name);
4380 else
4381 rc = attribute_update(ldap_handle, distinguished_name, "",
4382 "givenName", user_name);
4383
4384 if(strlen(middle) == 1)
4385 rc = attribute_update(ldap_handle, distinguished_name, middle,
4386 "initials", user_name);
4387 else
4388 rc = attribute_update(ldap_handle, distinguished_name, "",
4389 "initials", user_name);
4390
4391 if(strlen(last))
4392 rc = attribute_update(ldap_handle, distinguished_name, last,
4393 "sn", user_name);
4394 else
4395 rc = attribute_update(ldap_handle, distinguished_name, "",
4396 "sn", user_name);
4397
4398 if(ActiveDirectory)
4399 {
4400 rc = attribute_update(ldap_handle, distinguished_name, Uid, "uid",
4401 user_name);
4402 }
4403 else
4404 {
4405 rc = attribute_update(ldap_handle, distinguished_name, user_name, "uid",
4406 user_name);
4407 }
4408
4409 rc = attribute_update(ldap_handle, distinguished_name, MoiraId,
4410 "mitMoiraId", user_name);
4411
4412 n = 0;
4413 uid_v[0] = Uid;
4414
4415 if(ActiveDirectory)
4416 {
4417 if (!UseSFU30)
4418 {
4419 ADD_ATTR("uidNumber", uid_v, LDAP_MOD_REPLACE);
4420 }
4421 else
4422 {
4423 ADD_ATTR("msSFU30UidNumber", uid_v, LDAP_MOD_REPLACE);
4424 }
4425 }
4426 else
4427 {
4428 sprintf(principal, "%s@%s", user_name, PRIMARY_REALM);
4429 sprintf(status, "%d", State);
4430 principal_v[0] = principal;
4431 loginshell_v[0] = shell;
4432 mitMoiraClass_v[0] = class;
4433 mitMoiraStatus_v[0] = status;
4434 gid_v[0] = "101";
4435 ADD_ATTR("uidNumber", uid_v, LDAP_MOD_REPLACE);
4436 ADD_ATTR("gidNumber", gid_v, LDAP_MOD_REPLACE);
4437 ADD_ATTR("loginShell", loginshell_v, LDAP_MOD_REPLACE);
4438 ADD_ATTR("eduPersonPrincipalName", mail_v, LDAP_MOD_REPLACE);
4439 ADD_ATTR("mitMoiraClass", mitMoiraClass_v, LDAP_MOD_REPLACE);
4440 ADD_ATTR("mitMoiraStatus", mitMoiraStatus_v, LDAP_MOD_REPLACE);
4441 }
4442
4443 if ((State != US_NO_PASSWD) && (State != US_REGISTERED))
4444 {
4445 userAccountControl |= UF_ACCOUNTDISABLE;
4446
4447 if (Exchange)
4448 {
4449 hide_address_lists_v[0] = "TRUE";
4450 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
4451 LDAP_MOD_REPLACE);
4452 }
4453 }
4454 else
4455 {
4456 if (Exchange)
4457 {
4458 hide_address_lists_v[0] = NULL;
4459 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
4460 LDAP_MOD_REPLACE);
4461 }
4462 }
4463
4464 sprintf(userAccountControlStr, "%ld", userAccountControl);
4465 userAccountControl_v[0] = userAccountControlStr;
4466 ADD_ATTR("userAccountControl", userAccountControl_v, LDAP_MOD_REPLACE);
4467
4468 if (Exchange)
4469 {
4470 if (rc = moira_connect())
4471 {
c9ef9269 4472 critical_alert("Ldap incremental",
61a2844b 4473 "Error contacting Moira server : %s",
4474 error_message(rc));
4475 return;
4476 }
4477
4478 argv[0] = user_name;
4479
4480 if (!(rc = mr_query("get_pobox", 1, argv, save_query_info, save_argv)))
4481 {
4482 if(!strcmp(save_argv[1], "EXCHANGE") ||
4483 (strstr(save_argv[3], search_string) != NULL))
4484 {
4485 alt_recipient_v[0] = NULL;
4486 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_REPLACE);
4487
4488 argv[0] = exchange_acl;
4489 argv[1] = "USER";
4490 argv[2] = user_name;
4491
4492 rc = mr_query("add_member_to_list", 3, argv, NULL, NULL);
4493
4494 if ((rc) && (rc != MR_EXISTS))
4495 {
4496 com_err(whoami, 0, "Unable to add user %s to %s: %s",
4497 user_name, exchange_acl, error_message(rc));
4498 }
4499 }
4500 else
4501 {
4502 alt_recipient_v[0] = alt_recipient;
4503 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_REPLACE);
4504
4505 argv[0] = exchange_acl;
4506 argv[1] = "USER";
4507 argv[2] = user_name;
4508
4509 rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL);
4510
4511 if ((rc) && (rc != MR_NO_MATCH))
4512 {
4513 com_err(whoami, 0,
4514 "Unable to remove user %s from %s: %s, %d",
4515 user_name, exchange_acl, error_message(rc), rc);
4516 }
4517 }
4518 }
4519 else
4520 {
4521 alt_recipient_v[0] = alt_recipient;
4522 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_REPLACE);
4523
4524 argv[0] = exchange_acl;
4525 argv[1] = "USER";
4526 argv[2] = user_name;
4527
4528 rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL);
4529
4530 if ((rc) && (rc != MR_NO_MATCH))
4531 {
4532 com_err(whoami, 0,
4533 "Unable to remove user %s from %s: %s, %d",
4534 user_name, exchange_acl, error_message(rc), rc);
4535 }
4536 }
4537
4538 moira_disconnect();
4539 }
4540 else
4541 {
4542 mail_v[0] = contact_mail;
4543 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
4544 }
4545
4546 n = SetHomeDirectory(ldap_handle, user_name, distinguished_name, WinHomeDir,
4547 WinProfileDir, homedir_v, winProfile_v,
4548 drives_v, mods, LDAP_MOD_REPLACE, n);
4549
4550 if(ActiveDirectory)
4551 {
4552 sprintf(filter_exp, "(sAMAccountName=%s)", "UserTemplate.u");
4553 sprintf(search_path, "%s,%s", security_template_ou, dn_path);
4554 attr_array[0] = "sAMAccountName";
4555 attr_array[1] = NULL;
4556 group_count = 0;
4557 group_base = NULL;
4558
4559 if ((rc = linklist_build(ldap_handle, search_path, filter_exp,
4560 attr_array,
4561 &group_base, &group_count,
4562 LDAP_SCOPE_SUBTREE) != 0))
4563 return(1);
4564
4565 if (group_count != 1)
4566 {
4567 com_err(whoami, 0, "Unable to process user security template: %s - "
4568 "security not set", "UserTemplate.u");
4569 return(1);
4570 }
4571
4572 strcpy(TemplateDn, group_base->dn);
4573 strcpy(TemplateSamName, group_base->value);
4574 linklist_free(group_base);
4575 group_base = NULL;
4576 group_count = 0;
4577
4578 rc = ldap_search_ext_s(ldap_handle, search_path, LDAP_SCOPE_SUBTREE,
4579 filter_exp, NULL, 0, apsServerControls, NULL,
4580 NULL, 0, &psMsg);
4581
4582 if ((psMsg = ldap_first_entry(ldap_handle, psMsg)) == NULL)
4583 {
4584 com_err(whoami, 0, "Unable to find user security template: %s - "
4585 "security not set", "UserTemplate.u");
4586 return(1);
4587 }
4588
4589 ppsValues = ldap_get_values_len(ldap_handle, psMsg,
4590 "ntSecurityDescriptor");
4591
4592 if (ppsValues == NULL)
4593 {
4594 com_err(whoami, 0, "Unable to find user security template: %s - "
4595 "security not set", "UserTemplate.u");
4596 return(1);
4597 }
4598
4599 ADD_ATTR("ntSecurityDescriptor", (char **)ppsValues,
4600 LDAP_MOD_REPLACE | LDAP_MOD_BVALUES);
4601 }
4602
4603 mods[n] = NULL;
4604
4605 if ((rc = ldap_modify_s(ldap_handle, distinguished_name,
4606 mods)) != LDAP_SUCCESS)
4607 {
4608 OldUseSFU30 = UseSFU30;
4609 SwitchSFU(mods, &UseSFU30, n);
4610 if (OldUseSFU30 != UseSFU30)
4611 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
4612 if (rc)
4613 {
4614 com_err(whoami, 0, "Unable to modify user data for %s : %s",
4615 user_name, ldap_err2string(rc));
4616 }
4617 }
4618
4619 for (i = 0; i < n; i++)
4620 free(mods[i]);
4621
4622 return(rc);
4623}
4624
4625int user_rename(LDAP *ldap_handle, char *dn_path, char *before_user_name,
4626 char *user_name)
4627{
4628 LDAPMod *mods[20];
4629 char new_dn[256];
4630 char old_dn[256];
4631 char upn[256];
4632 char mail[256];
4633 char contact_mail[256];
4634 char proxy_address[256];
4635 char query_base_dn[256];
4636 char temp[256];
4637 char *userPrincipalName_v[] = {NULL, NULL};
4638 char *altSecurityIdentities_v[] = {NULL, NULL};
4639 char *name_v[] = {NULL, NULL};
4640 char *samAccountName_v[] = {NULL, NULL};
4641 char *mail_v[] = {NULL, NULL};
4642 char *mail_nickname_v[] = {NULL, NULL};
4643 char *proxy_address_v[] = {NULL, NULL};
4644 char *query_base_dn_v[] = {NULL, NULL};
4645 char *principal_v[] = {NULL, NULL};
4646 char principal[256];
4647 int n;
4648 int rc;
4649 int i;
4650
4651 if (!check_string(before_user_name))
4652 {
4653 com_err(whoami, 0,
4654 "Unable to process invalid LDAP user name %s", before_user_name);
4655 return(AD_INVALID_NAME);
4656 }
4657
4658 if (!check_string(user_name))
4659 {
4660 com_err(whoami, 0,
4661 "Unable to process invalid LDAP user name %s", user_name);
4662 return(AD_INVALID_NAME);
4663 }
4664
4665 strcpy(user_name, user_name);
4666
4667 if(ActiveDirectory)
4668 sprintf(old_dn, "cn=%s,%s,%s", before_user_name, user_ou, dn_path);
4669 else
4670 sprintf(old_dn, "uid=%s,%s,%s", before_user_name, user_ou, dn_path);
4671
4672 if(ActiveDirectory)
4673 sprintf(new_dn, "cn=%s", user_name);
4674 else
4675 sprintf(new_dn, "uid=%s", user_name);
4676
4677 sprintf(mail, "%s@%s", user_name, lowercase(ldap_domain));
4678 sprintf(contact_mail, "%s@mit.edu", user_name);
4679 sprintf(proxy_address, "SMTP:%s@%s", user_name, lowercase(ldap_domain));
4680 sprintf(principal, "%s@%s", user_name, PRIMARY_REALM);
4681
4682 if ((rc = ldap_rename_s(ldap_handle, old_dn, new_dn, NULL, TRUE,
4683 NULL, NULL)) != LDAP_SUCCESS)
4684 {
4685 com_err(whoami, 0, "Unable to rename user from %s to %s : %s",
4686 before_user_name, user_name, ldap_err2string(rc));
4687 return(rc);
4688 }
4689
4690 if (Exchange)
4691 {
4692 sprintf(temp, "cn=%s@mit.edu,%s,%s", before_user_name, contact_ou,
4693 dn_path);
4694
4695 if(rc = ldap_delete_s(ldap_handle, temp))
4696 {
4697 com_err(whoami, 0, "Unable to delete user contact for %s",
4698 user_name);
4699 }
4700
4701 if(contact_create(ldap_handle, dn_path, contact_mail, contact_ou))
4702 {
4703 com_err(whoami, 0, "Unable to create user contact %s", contact_mail);
4704 }
4705 }
4706
4707 name_v[0] = user_name;
4708 sprintf(upn, "%s@%s", user_name, ldap_domain);
4709 userPrincipalName_v[0] = upn;
4710 principal_v[0] = principal;
4711 sprintf(temp, "Kerberos:%s@%s", user_name, PRIMARY_REALM);
4712 sprintf(query_base_dn, "%s%s", ADDRESS_LIST_PREFIX, dn_path);
4713 altSecurityIdentities_v[0] = temp;
4714 samAccountName_v[0] = user_name;
4715 mail_v[0] = mail;
4716 mail_nickname_v[0] = user_name;
4717 proxy_address_v[0] = proxy_address;
4718 query_base_dn_v[0] = query_base_dn;
4719
4720 n = 0;
4721 ADD_ATTR("altSecurityIdentities", altSecurityIdentities_v, LDAP_MOD_REPLACE);
4722 ADD_ATTR("userPrincipalName", userPrincipalName_v, LDAP_MOD_REPLACE);
4723 ADD_ATTR("displayName", name_v, LDAP_MOD_REPLACE);
4724 ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_REPLACE);
4725
4726 if(!ActiveDirectory)
4727 {
4728 ADD_ATTR("uid", samAccountName_v, LDAP_MOD_REPLACE);
4729 ADD_ATTR("eduPersonPrincipalName", mail_v, LDAP_MOD_REPLACE);
4730 ADD_ATTR("displayName", name_v, LDAP_MOD_REPLACE);
4731 ADD_ATTR("eduPersonNickname", name_v, LDAP_MOD_REPLACE);
4732 }
4733
4734 if (Exchange)
4735 {
4736 ADD_ATTR("msExchQueryBaseDN", query_base_dn_v, LDAP_MOD_REPLACE);
4737 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
4738 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
4739 ADD_ATTR("proxyAddresses", proxy_address_v, LDAP_MOD_REPLACE);
4740 }
4741 else
4742 {
4743 mail_v[0] = contact_mail;
4744 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
4745 }
4746
4747 mods[n] = NULL;
4748
4749 if(ActiveDirectory)
4750 sprintf(new_dn, "cn=%s,%s,%s", user_name, user_ou, dn_path);
4751 else
4752 sprintf(new_dn, "uid=%s,%s,%s", user_name, user_ou, dn_path);
4753
4754 if ((rc = ldap_modify_s(ldap_handle, new_dn, mods)) != LDAP_SUCCESS)
4755 {
4756 com_err(whoami, 0,
4757 "Unable to modify user data for %s after renaming : %s",
4758 user_name, ldap_err2string(rc));
4759 }
4760
4761 for (i = 0; i < n; i++)
4762 free(mods[i]);
4763
4764 return(rc);
4765}
4766
4767int user_create(int ac, char **av, void *ptr)
4768{
4769 LDAPMod *mods[20];
4770 char new_dn[256];
4771 char user_name[256];
4772 char sam_name[256];
4773 char upn[256];
4774 char mail[256];
4775 char contact_mail[256];
4776 char proxy_address[256];
4777 char mail_nickname[256];
4778 char query_base_dn[256];
4779 char displayName[256];
4780 char address_book[256];
4781 char alt_recipient[256];
4782 char *cn_v[] = {NULL, NULL};
4783 char *objectClass_v[] = {"top", "person", "organizationalPerson",
4784 "user", NULL};
4785 char *objectClass_ldap_v[] = {"top",
4786 "eduPerson", "posixAccount",
4787 "apple-user", "shadowAccount",
4788 "microsoftComTop", "securityPrincipal",
4789 "inetOrgPerson", "user",
4790 "organizationalPerson", "person",
4791 "mailRecipient", NULL};
4792
4793 char *samAccountName_v[] = {NULL, NULL};
4794 char *altSecurityIdentities_v[] = {NULL, NULL};
4795 char *mitMoiraId_v[] = {NULL, NULL};
4796 char *mitMoiraClass_v[] = {NULL, NULL};
4797 char *mitMoiraStatus_v[] = {NULL, NULL};
4798 char *name_v[] = {NULL, NULL};
4799 char *desc_v[] = {NULL, NULL};
4800 char *userPrincipalName_v[] = {NULL, NULL};
4801 char *userAccountControl_v[] = {NULL, NULL};
4802 char *uid_v[] = {NULL, NULL};
4803 char *gid_v[] = {NULL, NULL};
4804 char *mitid_v[] = {NULL, NULL};
4805 char *homedir_v[] = {NULL, NULL};
4806 char *winProfile_v[] = {NULL, NULL};
4807 char *drives_v[] = {NULL, NULL};
4808 char *mail_v[] = {NULL, NULL};
4809 char *givenName_v[] = {NULL, NULL};
4810 char *sn_v[] = {NULL, NULL};
4811 char *initials_v[] = {NULL, NULL};
4812 char *displayName_v[] = {NULL, NULL};
4813 char *proxy_address_v[] = {NULL, NULL};
4814 char *mail_nickname_v[] = {NULL, NULL};
4815 char *query_base_dn_v[] = {NULL, NULL};
4816 char *address_book_v[] = {NULL, NULL};
4817 char *homeMDB_v[] = {NULL, NULL};
4818 char *homeServerName_v[] = {NULL, NULL};
4819 char *mdbUseDefaults_v[] = {NULL, NULL};
4820 char *mailbox_guid_v[] = {NULL, NULL};
4821 char *user_culture_v[] = {NULL, NULL};
4822 char *user_account_control_v[] = {NULL, NULL};
4823 char *msexch_version_v[] = {NULL, NULL};
4824 char *alt_recipient_v[] = {NULL, NULL};
4825 char *hide_address_lists_v[] = {NULL, NULL};
4826 char *principal_v[] = {NULL, NULL};
4827 char *loginshell_v[] = {NULL, NULL};
4828 char userAccountControlStr[80];
4829 char temp[1024];
4830 char principal[256];
4831 char filter_exp[1024];
4832 char search_path[512];
4833 char *attr_array[3];
4834 u_int userAccountControl = UF_NORMAL_ACCOUNT | UF_DONT_EXPIRE_PASSWD |
4835 UF_PASSWD_CANT_CHANGE;
4836 int n;
4837 int rc;
4838 int i;
4839 int OldUseSFU30;
4840 char **call_args;
4841 char WinHomeDir[1024];
4842 char WinProfileDir[1024];
4843 char *homeMDB;
4844 char *homeServerName;
4845 ULONG dwInfo;
4846 char acBERBuf[N_SD_BER_BYTES];
4847 LK_ENTRY *group_base;
4848 int group_count;
4849 char TemplateDn[512];
4850 char TemplateSamName[128];
4851 LDAP_BERVAL **ppsValues;
4852 LDAPControl sControl = {"1.2.840.113556.1.4.801",
4853 { N_SD_BER_BYTES, acBERBuf },
4854 TRUE};
4855 LDAPControl *apsServerControls[] = {&sControl, NULL};
4856 LDAPMessage *psMsg;
4857 char *argv[3];
4858 char *save_argv[7];
4859 char search_string[256];
4860 char *o_v[] = {NULL, NULL};
4861 char *p, *q;
4862 char *mail_routing_v[] = {NULL, NULL};
4863 char *c;
4864
4865 call_args = ptr;
4866
4867 dwInfo = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
4868 DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION;
4869 BEREncodeSecurityBits(dwInfo, acBERBuf);
4870
4871 if (!check_string(av[U_NAME]))
4872 {
4873 callback_rc = AD_INVALID_NAME;
4874 com_err(whoami, 0, "Unable to process invalid LDAP user name %s",
4875 av[U_NAME]);
4876 return(AD_INVALID_NAME);
4877 }
4878
4879 memset(WinHomeDir, '\0', sizeof(WinHomeDir));
4880 memset(WinProfileDir, '\0', sizeof(WinProfileDir));
4881 memset(displayName, '\0', sizeof(displayName));
4882 memset(query_base_dn, '\0', sizeof(query_base_dn));
4883 strcpy(WinHomeDir, av[U_WINHOMEDIR]);
4884 strcpy(WinProfileDir, av[U_WINPROFILEDIR]);
4885 strcpy(user_name, av[U_NAME]);
4886 sprintf(upn, "%s@%s", user_name, ldap_domain);
4887 sprintf(sam_name, "%s", av[U_NAME]);
4888
4889 if(strlen(av[U_FIRST])) {
4890 strcat(displayName, av[U_FIRST]);
4891 }
4892
4893 if(strlen(av[U_MIDDLE])) {
4894 if(strlen(av[U_FIRST]))
4895 strcat(displayName, " ");
4896
4897 strcat(displayName, av[U_MIDDLE]);
4898 }
4899
4900 if(strlen(av[U_LAST])) {
4901 if(strlen(av[U_FIRST]) || strlen(av[U_MIDDLE]))
4902 strcat(displayName, " ");
4903
4904 strcat(displayName, av[U_LAST]);
4905 }
4906
4907 samAccountName_v[0] = sam_name;
4908 if ((atoi(av[U_STATE]) != US_NO_PASSWD) &&
4909 (atoi(av[U_STATE]) != US_REGISTERED))
4910 {
4911 userAccountControl |= UF_ACCOUNTDISABLE;
4912
4913 if (Exchange)
4914 {
4915 hide_address_lists_v[0] = "TRUE";
4916 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
4917 LDAP_MOD_ADD);
4918 }
4919 }
4920
4921 sprintf(userAccountControlStr, "%ld", userAccountControl);
4922 userAccountControl_v[0] = userAccountControlStr;
4923 userPrincipalName_v[0] = upn;
4924
4925 if(ActiveDirectory)
4926 cn_v[0] = user_name;
4927 else
4928 cn_v[0] = displayName;
4929
4930 name_v[0] = user_name;
4931 desc_v[0] = "Auto account created by Moira";
4932 mail_v[0] = mail;
4933 givenName_v[0] = av[U_FIRST];
4934
4935 if(ActiveDirectory)
4936 sn_v[0] = av[U_LAST];
4937 else
4938 if(strlen(av[U_LAST]))
4939 sn_v[0] = av[U_LAST];
4940 else
4941 sn_v[0] = av[U_NAME];
4942
4943 displayName_v[0] = displayName;
4944 mail_nickname_v[0] = user_name;
4945 o_v[0] = "Massachusetts Institute of Technology";
4946
4947 sprintf(temp, "Kerberos:%s@%s", user_name, PRIMARY_REALM);
4948 sprintf(principal, "%s@%s", user_name, PRIMARY_REALM);
4949 altSecurityIdentities_v[0] = temp;
4950 principal_v[0] = principal;
4951
4952 if(ActiveDirectory)
4953 sprintf(new_dn, "cn=%s,%s,%s", user_name, user_ou, call_args[1]);
4954 else
4955 sprintf(new_dn, "uid=%s,%s,%s", user_name, user_ou, call_args[1]);
4956
4957 sprintf(mail,"%s@%s", user_name, lowercase(ldap_domain));
4958 sprintf(contact_mail, "%s@mit.edu", user_name);
4959 sprintf(query_base_dn, "%s%s", ADDRESS_LIST_PREFIX, call_args[1]);
4960 query_base_dn_v[0] = query_base_dn;
4961 sprintf(alt_recipient, "cn=%s@mit.edu,%s,%s", user_name, contact_ou,
4962 call_args[1]);
4963 sprintf(search_string, "@%s", uppercase(ldap_domain));
4964
4965 if (Exchange)
4966 {
4967 if(contact_create((LDAP *)call_args[0], call_args[1], contact_mail,
4968 contact_ou))
4969 {
4970 com_err(whoami, 0, "Unable to create user contact %s",
4971 contact_mail);
4972 }
4973
4974 if(find_homeMDB((LDAP *)call_args[0], call_args[1], &homeMDB,
4975 &homeServerName))
4976 {
4977 com_err(whoami, 0, "Unable to locate homeMB and homeServerName");
4978 return(1);
4979 }
4980
4981 com_err(whoami, 0, "homeMDB:%s", homeMDB);
4982 com_err(whoami, 0, "homeServerName:%s", homeServerName);
4983
4984 homeMDB_v[0] = homeMDB;
4985 homeServerName_v[0] = homeServerName;
4986 }
4987
4988 n = 0;
4989
4990 ADD_ATTR("cn", cn_v, LDAP_MOD_ADD);
4991
4992 if(ActiveDirectory)
4993 {
4994 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
4995 }
4996 else
4997 {
4998 ADD_ATTR("objectClass", objectClass_ldap_v, LDAP_MOD_ADD);
4999 }
5000
5001 ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_ADD);
5002 ADD_ATTR("userPrincipalName", userPrincipalName_v, LDAP_MOD_ADD);
5003 ADD_ATTR("userAccountControl", userAccountControl_v, LDAP_MOD_ADD);
5004 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
5005 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
5006
5007 if (Exchange)
5008 {
5009 ADD_ATTR("msExchQueryBaseDN", query_base_dn_v, LDAP_MOD_ADD);
5010 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_ADD);
5011 ADD_ATTR("homeMDB", homeMDB_v, LDAP_MOD_ADD);
5012 mdbUseDefaults_v[0] = "TRUE";
5013 ADD_ATTR("mdbUseDefaults", mdbUseDefaults_v, LDAP_MOD_ADD);
5014 ADD_ATTR("msExchHomeServerName", homeServerName_v, LDAP_MOD_ADD);
5015
5016 argv[0] = user_name;
5017
5018 if (!(rc = mr_query("get_pobox", 1, argv, save_query_info, save_argv)))
5019 {
5020 if(!strcmp(save_argv[1], "EXCHANGE") ||
5021 (strstr(save_argv[3], search_string) != NULL))
5022 {
5023 argv[0] = exchange_acl;
5024 argv[1] = "USER";
5025 argv[2] = user_name;
5026
5027 rc = mr_query("add_member_to_list", 3, argv, NULL, NULL);
5028
5029 if ((rc) && (rc != MR_EXISTS))
5030 {
5031 com_err(whoami, 0, "Unable to add user %s to %s: %s",
5032 user_name, exchange_acl, error_message(rc));
5033 }
5034 }
5035 else
5036 {
5037 alt_recipient_v[0] = alt_recipient;
5038 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_ADD);
5039 }
5040 }
5041 else
5042 {
5043 alt_recipient_v[0] = alt_recipient;
5044 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_ADD);
5045
5046 com_err(whoami, 0, "Unable to fetch pobox for %s", user_name);
5047 }
5048 }
5049 else
5050 {
5051 mail_v[0] = contact_mail;
5052 ADD_ATTR("mail", mail_v, LDAP_MOD_ADD);
5053 }
5054
5055 if(strlen(av[U_FIRST])) {
5056 ADD_ATTR("givenName", givenName_v, LDAP_MOD_ADD);
5057 }
5058
5059 if(strlen(av[U_LAST]) || strlen(av[U_NAME])) {
5060 ADD_ATTR("sn", sn_v, LDAP_MOD_ADD);
5061 }
5062
5063 if(strlen(av[U_FIRST]) || strlen(av[U_MIDDLE]) || strlen(av[U_LAST])) {
5064 ADD_ATTR("displayName", displayName_v, LDAP_MOD_ADD);
5065
5066 if(!ActiveDirectory)
5067 {
5068 ADD_ATTR("eduPersonNickname", displayName_v, LDAP_MOD_ADD);
5069 }
5070 } else {
5071 ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
5072
5073 if(!ActiveDirectory)
5074 {
5075 ADD_ATTR("eduPersonNickname", name_v, LDAP_MOD_ADD);
5076 }
5077 }
5078
5079 if (strlen(av[U_MIDDLE]) == 1) {
5080 initials_v[0] = av[U_MIDDLE];
5081 ADD_ATTR("initials", initials_v, LDAP_MOD_ADD);
5082 }
5083
5084 if (strlen(call_args[2]) != 0)
5085 {
5086 mitMoiraId_v[0] = call_args[2];
5087 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_ADD);
5088 }
5089
5090 ADD_ATTR("altSecurityIdentities", altSecurityIdentities_v, LDAP_MOD_ADD);
5091
5092 if(!ActiveDirectory)
5093 {
5094 loginshell_v[0] = av[U_SHELL];
5095 mitMoiraClass_v[0] = av[U_CLASS];
5096 mitMoiraStatus_v[0] = av[U_STATE];
5097 ADD_ATTR("loginShell", loginshell_v, LDAP_MOD_ADD);
5098 ADD_ATTR("uid", samAccountName_v, LDAP_MOD_ADD);
5099 ADD_ATTR("eduPersonPrincipalName", mail_v, LDAP_MOD_ADD);
5100 ADD_ATTR("o", o_v, LDAP_MOD_ADD);
5101 ADD_ATTR("mitMoiraClass", mitMoiraClass_v, LDAP_MOD_ADD);
5102 ADD_ATTR("mitMoiraStatus", mitMoiraStatus_v, LDAP_MOD_ADD);
5103 }
5104
5105 if (strlen(av[U_UID]) != 0)
5106 {
5107 uid_v[0] = av[U_UID];
5108
5109 if(ActiveDirectory)
5110 {
5111 ADD_ATTR("uid", uid_v, LDAP_MOD_ADD);
5112 }
5113 else
5114 {
5115 gid_v[0] = "101";
5116 ADD_ATTR("uidNumber", uid_v, LDAP_MOD_ADD);
5117 ADD_ATTR("gidNumber", gid_v, LDAP_MOD_ADD);
5118 }
5119
5120 if(ActiveDirectory)
5121 {
5122 if (!UseSFU30)
5123 {
5124 ADD_ATTR("uidNumber", uid_v, LDAP_MOD_ADD);
5125 }
5126 else
5127 {
5128 ADD_ATTR("msSFU30UidNumber", uid_v, LDAP_MOD_ADD);
5129 }
5130 }
5131 }
5132
5133 if ((strlen(av[U_MITID]) != 0) && (av[U_MITID][0] == '9'))
5134 mitid_v[0] = av[U_MITID];
5135 else
5136 mitid_v[0] = "none";
5137
5138 ADD_ATTR("employeeID", mitid_v, LDAP_MOD_ADD);
5139
5140 n = SetHomeDirectory((LDAP *)call_args[0], user_name, new_dn,
5141 WinHomeDir, WinProfileDir, homedir_v, winProfile_v,
5142 drives_v, mods, LDAP_MOD_ADD, n);
5143
5144 if(ActiveDirectory)
5145 {
5146 sprintf(filter_exp, "(sAMAccountName=%s)", "UserTemplate.u");
5147 sprintf(search_path, "%s,%s", security_template_ou, call_args[1]);
5148 attr_array[0] = "sAMAccountName";
5149 attr_array[1] = NULL;
5150 group_count = 0;
5151 group_base = NULL;
5152
5153 if ((rc = linklist_build((LDAP *)call_args[0], search_path, filter_exp,
5154 attr_array, &group_base, &group_count,
5155 LDAP_SCOPE_SUBTREE) != 0))
5156 return(1);
5157
5158 if (group_count != 1)
5159 {
5160 com_err(whoami, 0, "Unable to process user security template: %s - "
5161 "security not set", "UserTemplate.u");
5162 return(1);
5163 }
5164
5165 strcpy(TemplateDn, group_base->dn);
5166 strcpy(TemplateSamName, group_base->value);
5167 linklist_free(group_base);
5168 group_base = NULL;
5169 group_count = 0;
5170
5171 rc = ldap_search_ext_s((LDAP *)call_args[0], search_path,
5172 LDAP_SCOPE_SUBTREE, filter_exp, NULL, 0,
5173 apsServerControls, NULL,
5174 NULL, 0, &psMsg);
5175
5176 if ((psMsg = ldap_first_entry((LDAP *)call_args[0], psMsg)) == NULL)
5177 {
5178 com_err(whoami, 0, "Unable to find user security template: %s - "
5179 "security not set", "UserTemplate.u");
5180 return(1);
5181 }
5182
5183 ppsValues = ldap_get_values_len((LDAP *)call_args[0], psMsg,
5184 "ntSecurityDescriptor");
5185 if (ppsValues == NULL)
5186 {
5187 com_err(whoami, 0, "Unable to find user security template: %s - "
5188 "security not set", "UserTemplate.u");
5189 return(1);
5190 }
5191
5192 ADD_ATTR("ntSecurityDescriptor", (char **)ppsValues,
5193 LDAP_MOD_REPLACE | LDAP_MOD_BVALUES);
5194 }
5195
5196 mods[n] = NULL;
5197
5198 rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL);
5199
5200 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
5201 {
5202 OldUseSFU30 = UseSFU30;
5203 SwitchSFU(mods, &UseSFU30, n);
5204 if (OldUseSFU30 != UseSFU30)
5205 rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL);
5206 }
5207
5208 for (i = 0; i < n; i++)
5209 free(mods[i]);
5210
5211 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
5212 {
5213 com_err(whoami, 0, "Unable to create user %s : %s",
5214 user_name, ldap_err2string(rc));
5215 callback_rc = rc;
5216 return(rc);
5217 }
5218
5219 if ((rc == LDAP_SUCCESS) && (SetPassword))
5220 {
5221 if ((rc = set_password(sam_name, "", ldap_domain)) != 0)
5222 {
5223 ad_kdc_disconnect();
5224 if (!ad_server_connect(default_server, ldap_domain))
5225 {
5226 com_err(whoami, 0, "Unable to set password for user %s : %s",
5227 user_name,
5228 "cannot get changepw ticket from windows domain");
5229 }
5230 else
5231 {
5232 if ((rc = set_password(sam_name, "", ldap_domain)) != 0)
5233 {
5234 com_err(whoami, 0, "Unable to set password for user %s "
5235 ": %ld", user_name, rc);
5236 }
5237 }
5238 }
5239 }
5240
5241 if(!ActiveDirectory)
5242 {
5243 if (rc = moira_connect())
5244 {
c9ef9269 5245 critical_alert("Ldap incremental",
61a2844b 5246 "Error contacting Moira server : %s",
5247 error_message(rc));
5248 return;
5249 }
5250
5251 argv[0] = user_name;
5252
5253 if (!(rc = mr_query("get_pobox", 1, argv, save_query_info, save_argv)))
5254 {
0384092e 5255 n = 0;
5256 ADD_ATTR("mailRoutingAddress", mail_routing_v, LDAP_MOD_REPLACE);
5257 mods[n] = NULL;
5258 rc = ldap_modify_s((LDAP *)call_args[0], new_dn, mods);
5259
5260 if (rc == LDAP_ALREADY_EXISTS || rc == LDAP_TYPE_OR_VALUE_EXISTS)
5261 rc = LDAP_SUCCESS;
5262
5263 if(rc)
5264 com_err(whoami, 0,
5265 "Unable to set the mailRoutingAddress for %s : %s",
5266 user_name, ldap_err2string(rc));
5267
61a2844b 5268 p = strdup(save_argv[3]);
5269
5270 if((c = strchr(p, ',')) != NULL) {
5271 q = strtok(p, ",");
5272 StringTrim(q);
5273
5274 if ((c = strchr(q, '@')) == NULL)
5275 sprintf(temp, "%s@mit.edu", q);
5276 else
5277 sprintf(temp, "%s", q);
5278
5279 if(email_isvalid(temp) && atoi(av[U_STATE]) != US_DELETED)
5280 {
5281 mail_routing_v[0] = temp;
5282
5283 n = 0;
5284 ADD_ATTR("mailRoutingAddress", mail_routing_v, LDAP_MOD_ADD);
5285 mods[n] = NULL;
5286 rc = ldap_modify_s((LDAP *)call_args[0], new_dn, mods);
5287
5288 if (rc == LDAP_ALREADY_EXISTS ||
5289 rc == LDAP_TYPE_OR_VALUE_EXISTS)
5290 rc = LDAP_SUCCESS;
5291
5292 if(rc)
5293 com_err(whoami, 0,
5294 "Unable to set the mailRoutingAddress for %s : %s",
5295 user_name, ldap_err2string(rc));
5296 }
5297
5298 while((q = strtok(NULL, ",")) != NULL) {
5299 StringTrim(q);
5300
5301 if((c = strchr(q, '@')) == NULL)
5302 sprintf(temp, "%s@mit.edu", q);
5303 else
5304 sprintf(temp, "%s", q);
5305
5306 if(email_isvalid(temp) && atoi(av[U_STATE]) != US_DELETED)
5307 {
5308 mail_routing_v[0] = temp;
5309
5310 n = 0;
5311 ADD_ATTR("mailRoutingAddress", mail_routing_v, LDAP_MOD_ADD);
5312 mods[n] = NULL;
5313 rc = ldap_modify_s((LDAP *)call_args[0], new_dn, mods);
5314
5315 if (rc == LDAP_ALREADY_EXISTS ||
5316 rc == LDAP_TYPE_OR_VALUE_EXISTS)
5317 rc = LDAP_SUCCESS;
5318
5319 if(rc)
5320 com_err(whoami, 0,
5321 "Unable to set the mailRoutingAddress for %s : %s",
5322 user_name, ldap_err2string(rc));
5323 }
5324 }
5325 } else {
5326 StringTrim(p);
5327
5328 if((c = strchr(p, '@')) == NULL)
5329 sprintf(temp, "%s@mit.edu", p);
5330 else
5331 sprintf(temp, "%s", p);
5332
5333 if(email_isvalid(temp) && atoi(av[U_STATE]) != US_DELETED)
5334 {
5335 mail_routing_v[0] = temp;
5336
5337 n = 0;
5338 ADD_ATTR("mailRoutingAddress", mail_routing_v, LDAP_MOD_ADD);
5339 mods[n] = NULL;
5340 rc = ldap_modify_s((LDAP *)call_args[0], new_dn, mods);
5341
5342 if (rc == LDAP_ALREADY_EXISTS ||
5343 rc == LDAP_TYPE_OR_VALUE_EXISTS)
5344 rc = LDAP_SUCCESS;
5345
5346 if(rc)
5347 com_err(whoami, 0,
5348 "Unable to set the mailRoutingAddress for %s : %s",
5349 user_name, ldap_err2string(rc));
5350 }
5351 }
5352 }
5353 moira_disconnect();
5354 }
5355
5356 return(0);
5357}
5358
5359int user_change_status(LDAP *ldap_handle, char *dn_path,
5360 char *user_name, char *MoiraId,
5361 int operation)
5362{
5363 char filter[128];
5364 char *attr_array[3];
5365 char temp[256];
5366 char distinguished_name[1024];
5367 char **modvalues;
5368 char *mitMoiraId_v[] = {NULL, NULL};
5369 LDAPMod *mods[20];
5370 LK_ENTRY *group_base;
5371 int group_count;
5372 int rc;
5373 int i;
5374 int n;
5375 ULONG ulongValue;
5376
5377 if (!check_string(user_name))
5378 {
5379 com_err(whoami, 0, "Unable to process invalid LDAP user name %s",
5380 user_name);
5381 return(AD_INVALID_NAME);
5382 }
5383
5384 group_count = 0;
5385 group_base = NULL;
5386
5387 if (strlen(MoiraId) != 0)
5388 {
5389 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
5390 attr_array[0] = "UserAccountControl";
5391 attr_array[1] = NULL;
5392 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5393 &group_base, &group_count,
5394 LDAP_SCOPE_SUBTREE)) != 0)
5395 {
5396 com_err(whoami, 0, "Unable to process user %s : %s",
5397 user_name, ldap_err2string(rc));
5398 return(rc);
5399 }
5400 }
5401
5402 if (group_count != 1)
5403 {
5404 linklist_free(group_base);
5405 group_count = 0;
5406 group_base = NULL;
5407 sprintf(filter, "(sAMAccountName=%s)", user_name);
5408 attr_array[0] = "UserAccountControl";
5409 attr_array[1] = NULL;
5410 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5411 &group_base, &group_count,
5412 LDAP_SCOPE_SUBTREE)) != 0)
5413 {
5414 com_err(whoami, 0, "Unable to process user %s : %s",
5415 user_name, ldap_err2string(rc));
5416 return(rc);
5417 }
5418 }
5419
5420 if (group_count != 1)
5421 {
5422 linklist_free(group_base);
c9ef9269 5423 com_err(whoami, 0, "Unable to find user %s in directory",
61a2844b 5424 user_name);
5425 return(LDAP_NO_SUCH_OBJECT);
5426 }
5427
5428 strcpy(distinguished_name, group_base->dn);
5429 ulongValue = atoi((*group_base).value);
5430
5431 if (operation == MEMBER_DEACTIVATE)
5432 ulongValue |= UF_ACCOUNTDISABLE;
5433 else
5434 ulongValue &= ~UF_ACCOUNTDISABLE;
5435
5436 sprintf(temp, "%ld", ulongValue);
5437
5438 if ((rc = construct_newvalues(group_base, group_count, (*group_base).value,
5439 temp, &modvalues, REPLACE)) == 1)
5440 goto cleanup;
5441
5442 linklist_free(group_base);
5443 group_base = NULL;
5444 group_count = 0;
5445 n = 0;
5446 ADD_ATTR("UserAccountControl", modvalues, LDAP_MOD_REPLACE);
5447
5448 if (strlen(MoiraId) != 0)
5449 {
5450 mitMoiraId_v[0] = MoiraId;
5451 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_REPLACE);
5452 }
5453
5454 mods[n] = NULL;
5455 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
5456
5457 for (i = 0; i < n; i++)
5458 free(mods[i]);
5459
5460 free_values(modvalues);
5461
5462 if (rc != LDAP_SUCCESS)
5463 {
5464 com_err(whoami, 0, "Unable to change status of user %s : %s",
5465 user_name, ldap_err2string(rc));
5466 }
5467
5468 cleanup:
5469 return(rc);
5470}
5471
5472int user_delete(LDAP *ldap_handle, char *dn_path,
5473 char *u_name, char *MoiraId)
5474{
5475 char filter[128];
5476 char *attr_array[3];
5477 char distinguished_name[1024];
5478 char user_name[512];
5479 LK_ENTRY *group_base;
5480 int group_count;
5481 int rc;
5482 char temp[256];
5483
5484 if (!check_string(u_name))
5485 return(AD_INVALID_NAME);
5486
5487 strcpy(user_name, u_name);
5488 group_count = 0;
5489 group_base = NULL;
5490
5491 if (strlen(MoiraId) != 0)
5492 {
5493 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
5494 attr_array[0] = "name";
5495 attr_array[1] = NULL;
5496 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5497 &group_base, &group_count,
5498 LDAP_SCOPE_SUBTREE)) != 0)
5499 {
5500 com_err(whoami, 0, "Unable to process user %s : %s",
5501 user_name, ldap_err2string(rc));
5502 goto cleanup;
5503 }
5504 }
5505
5506 if (group_count != 1)
5507 {
5508 linklist_free(group_base);
5509 group_count = 0;
5510 group_base = NULL;
5511 sprintf(filter, "(sAMAccountName=%s)", user_name);
5512 attr_array[0] = "name";
5513 attr_array[1] = NULL;
5514 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5515 &group_base, &group_count,
5516 LDAP_SCOPE_SUBTREE)) != 0)
5517 {
5518 com_err(whoami, 0, "Unable to process user %s : %s",
5519 user_name, ldap_err2string(rc));
5520 goto cleanup;
5521 }
5522 }
5523
5524 if (group_count != 1)
5525 {
c9ef9269 5526 com_err(whoami, 0, "Unable to find user %s in directory",
61a2844b 5527 user_name);
5528 goto cleanup;
5529 }
5530
5531 strcpy(distinguished_name, group_base->dn);
5532
5533 if (rc = ldap_delete_s(ldap_handle, distinguished_name))
5534 {
5535 com_err(whoami, 0, "Unable to process user %s : %s",
5536 user_name, ldap_err2string(rc));
5537 }
5538
5539 /* Need to add code to delete mit.edu contact */
5540
5541 if (Exchange)
5542 {
5543 sprintf(temp, "cn=%s@mit.edu,%s,%s", user_name, contact_ou, dn_path);
5544
5545 if(rc = ldap_delete_s(ldap_handle, temp))
5546 {
5547 com_err(whoami, 0, "Unable to delete user contact for %s",
5548 user_name);
5549 }
5550 }
5551
5552 cleanup:
5553 linklist_free(group_base);
5554
5555 return(0);
5556}
5557
5558void linklist_free(LK_ENTRY *linklist_base)
5559{
5560 LK_ENTRY *linklist_previous;
5561
5562 while (linklist_base != NULL)
5563 {
5564 if (linklist_base->dn != NULL)
5565 free(linklist_base->dn);
5566
5567 if (linklist_base->attribute != NULL)
5568 free(linklist_base->attribute);
5569
5570 if (linklist_base->value != NULL)
5571 free(linklist_base->value);
5572
5573 if (linklist_base->member != NULL)
5574 free(linklist_base->member);
5575
5576 if (linklist_base->type != NULL)
5577 free(linklist_base->type);
5578
5579 if (linklist_base->list != NULL)
5580 free(linklist_base->list);
5581
5582 linklist_previous = linklist_base;
5583 linklist_base = linklist_previous->next;
5584 free(linklist_previous);
5585 }
5586}
5587
5588void free_values(char **modvalues)
5589{
5590 int i;
5591
5592 i = 0;
5593
5594 if (modvalues != NULL)
5595 {
5596 while (modvalues[i] != NULL)
5597 {
5598 free(modvalues[i]);
5599 modvalues[i] = NULL;
5600 ++i;
5601 }
5602 free(modvalues);
5603 }
5604}
5605
5606static int illegalchars[] = {
5607 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^@ - ^O */
5608 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^P - ^_ */
5609 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, /* SPACE - / */
5610 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, /* 0 - ? */
5611 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* @ - O */
5612 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, /* P - _ */
5613 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ` - o */
5614 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, /* p - ^? */
5615 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5616 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5617 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5618 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5619 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5620 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5621 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5622 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5623};
5624
5625static int illegalchars_ldap[] = {
5626 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^@ - ^O */
5627 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^P - ^_ */
5628 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, /* SPACE - / */
5629 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, /* 0 - ? */
5630 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* @ - O */
5631 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, /* P - _ */
5632 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ` - o */
5633 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, /* p - ^? */
5634 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5635 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5636 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5637 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5638 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5639 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5640 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5641 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5642};
5643
5644int check_string(char *s)
5645{
5646 char character;
5647
5648 for (; *s; s++)
5649 {
5650 character = *s;
5651
5652 if (isupper(character))
5653 character = tolower(character);
5654
5655 if(ActiveDirectory)
5656 {
5657 if (illegalchars[(unsigned) character])
5658 return 0;
5659 }
5660 else
5661 {
5662 if (illegalchars_ldap[(unsigned) character])
5663 return 0;
5664 }
5665 }
5666
5667 return(1);
5668}
5669
5670int check_container_name(char *s)
5671{
5672 char character;
5673
5674 for (; *s; s++)
5675 {
5676 character = *s;
5677
5678 if (isupper(character))
5679 character = tolower(character);
5680
5681 if (character == ' ')
5682 continue;
5683
5684 if (illegalchars[(unsigned) character])
5685 return 0;
5686 }
5687
5688 return(1);
5689}
5690
5691int mr_connect_cl(char *server, char *client, int version, int auth)
5692{
5693 int status;
5694 char *motd;
5695 char temp[128];
5696
5697 status = mr_connect(server);
5698
5699 if (status)
5700 {
5701 com_err(whoami, status, "while connecting to Moira");
5702 return status;
5703 }
5704
5705 status = mr_motd(&motd);
5706
5707 if (status)
5708 {
5709 mr_disconnect();
5710 com_err(whoami, status, "while checking server status");
5711 return status;
5712 }
5713
5714 if (motd)
5715 {
5716 sprintf(temp, "The Moira server is currently unavailable: %s", motd);
5717 com_err(whoami, status, temp);
5718 mr_disconnect();
5719 return status;
5720 }
5721
5722 status = mr_version(version);
5723
5724 if (status)
5725 {
5726 if (status == MR_UNKNOWN_PROC)
5727 {
5728 if (version > 2)
5729 status = MR_VERSION_HIGH;
5730 else
5731 status = MR_SUCCESS;
5732 }
5733
5734 if (status == MR_VERSION_HIGH)
5735 {
5736 com_err(whoami, 0, "Warning: This client is running newer code "
5737 "than the server.");
5738 com_err(whoami, 0, "Some operations may not work.");
5739 }
5740 else if (status && status != MR_VERSION_LOW)
5741 {
5742 com_err(whoami, status, "while setting query version number.");
5743 mr_disconnect();
5744 return status;
5745 }
5746 }
5747
5748 if (auth)
5749 {
5750 status = mr_krb5_auth(client);
5751 if (status)
5752 {
5753 com_err(whoami, status, "while authenticating to Moira.");
5754 mr_disconnect();
5755 return status;
5756 }
5757 }
5758
5759 return MR_SUCCESS;
5760}
5761
5762void AfsToWinAfs(char* path, char* winPath)
5763{
5764 char* pathPtr;
5765 char* winPathPtr;
5766 strcpy(winPath, WINAFS);
5767 pathPtr = path + strlen(AFS);
5768 winPathPtr = winPath + strlen(WINAFS);
5769
5770 while (*pathPtr)
5771 {
5772 if (*pathPtr == '/')
5773 *winPathPtr = '\\';
5774 else
5775 *winPathPtr = *pathPtr;
5776
5777 pathPtr++;
5778 winPathPtr++;
5779 }
5780}
5781
5782int GetAceInfo(int ac, char **av, void *ptr)
5783{
5784 char **call_args;
5785 int security_flag;
5786
5787 call_args = ptr;
5788
5789 strcpy(call_args[0], av[L_ACE_TYPE]);
5790 strcpy(call_args[1], av[L_ACE_NAME]);
5791 security_flag = 0;
5792 get_group_membership(call_args[2], call_args[3], &security_flag, av);
5793 return(LDAP_SUCCESS);
5794}
5795
5796int checkADname(LDAP *ldap_handle, char *dn_path, char *Name)
5797{
5798 char filter[128];
5799 char *attr_array[3];
5800 int group_count;
5801 int rc;
5802 LK_ENTRY *group_base;
5803
5804 group_count = 0;
5805 group_base = NULL;
5806
5807 sprintf(filter, "(sAMAccountName=%s)", Name);
5808 attr_array[0] = "sAMAccountName";
5809 attr_array[1] = NULL;
5810
5811 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5812 &group_base, &group_count,
5813 LDAP_SCOPE_SUBTREE)) != 0)
5814 {
5815 com_err(whoami, 0, "Unable to process ACE name %s : %s",
5816 Name, ldap_err2string(rc));
5817 return(1);
5818 }
5819
5820 linklist_free(group_base);
5821 group_base = NULL;
5822
5823 if (group_count == 0)
5824 return(0);
5825
5826 return(1);
5827}
5828
5829#define MAX_ACE 7
5830
5831int ProcessAce(LDAP *ldap_handle, char *dn_path, char *Name, char *Type,
5832 int UpdateGroup, int *ProcessGroup, char *maillist)
5833{
5834 char *av[2];
5835 char GroupName[256];
5836 char *call_args[7];
5837 int rc;
5838 char *AceInfo[4];
5839 char AceType[32];
5840 char AceName[128];
5841 char AceMembership[2];
5842 char AceOu[256];
5843 char temp[128];
5844 char *save_argv[U_END];
5845
5846 if (!SetGroupAce)
5847 {
5848 com_err(whoami, 0, "ProcessAce disabled, skipping");
5849 return(0);
5850 }
5851
5852 strcpy(GroupName, Name);
5853
5854 if (strcasecmp(Type, "LIST"))
5855 return(1);
5856
5857 while (1)
5858 {
5859 av[0] = GroupName;
5860 AceInfo[0] = AceType;
5861 AceInfo[1] = AceName;
5862 AceInfo[2] = AceMembership;
5863 AceInfo[3] = AceOu;
5864 memset(AceType, '\0', sizeof(AceType));
5865 memset(AceName, '\0', sizeof(AceName));
5866 memset(AceMembership, '\0', sizeof(AceMembership));
5867 memset(AceOu, '\0', sizeof(AceOu));
5868 callback_rc = 0;
5869
5870 if (rc = mr_query("get_list_info", 1, av, GetAceInfo, AceInfo))
5871 {
a2aa35d9 5872 if(rc != MR_LIST)
5873 com_err(whoami, 0, "Unable to get ACE info for list %s : %s",
5874 GroupName, error_message(rc));
5875
61a2844b 5876 return(1);
5877 }
5878
5879 if (callback_rc)
5880 {
5881 com_err(whoami, 0, "Unable to get ACE info for list %s", GroupName);
5882 return(1);
5883 }
5884
5885 if ((strcasecmp(AceType, "USER")) && (strcasecmp(AceType, "LIST")))
5886 return(0);
5887
5888 strcpy(temp, AceName);
5889
5890 if (!strcasecmp(AceType, "LIST"))
5891 sprintf(temp, "%s%s", AceName, group_suffix);
5892
5893 if (!UpdateGroup)
5894 {
5895 if (checkADname(ldap_handle, dn_path, temp))
5896 return(0);
5897
5898 (*ProcessGroup) = 1;
5899 }
5900
5901 if (!strcasecmp(AceInfo[0], "LIST"))
5902 {
5903 if (make_new_group(ldap_handle, dn_path, "", AceName, AceOu,
5904 AceMembership, 0, UpdateGroup, maillist))
5905 return(1);
33448741 5906
5907 populate_group(ldap_handle, dn_path, AceName, AceOu, AceMembership,
5908 0, "");
61a2844b 5909 }
5910 else if (!strcasecmp(AceInfo[0], "USER"))
5911 {
5912 av[0] = AceName;
5913 call_args[0] = (char *)ldap_handle;
5914 call_args[1] = dn_path;
5915 call_args[2] = "";
5916 call_args[3] = NULL;
5917 callback_rc = 0;
5918
5919 if (rc = mr_query("get_user_account_by_login", 1, av,
5920 save_query_info, save_argv))
5921 {
5922 com_err(whoami, 0, "Unable to process user ACE %s for group %s.",
5923 AceName, Name);
5924 return(1);
5925 }
5926
5927 if (rc = user_create(U_END, save_argv, call_args))
5928 {
5929 com_err(whoami, 0, "Unable to process user ACE %s for group %s.",
5930 AceName, Name);
5931 return(1);
5932 }
5933
5934 if (callback_rc)
5935 {
5936 com_err(whoami, 0, "Unable to process user Ace %s for group %s",
5937 AceName, Name);
5938 return(1);
5939 }
5940
5941 return(0);
5942 }
5943 else
5944 return(1);
5945
5946 if (!strcasecmp(AceType, "LIST"))
5947 {
5948 if (!strcasecmp(GroupName, AceName))
5949 return(0);
5950 }
5951
5952 strcpy(GroupName, AceName);
5953 }
5954
5955 return(1);
5956}
5957
5958int make_new_group(LDAP *ldap_handle, char *dn_path, char *MoiraId,
5959 char *group_name, char *group_ou, char *group_membership,
5960 int group_security_flag, int updateGroup, char *maillist)
5961{
5962 char *av[3];
5963 char *call_args[8];
5964 int rc;
5965 LK_ENTRY *group_base;
5966 int group_count;
5967 char filter[128];
5968 char *attr_array[3];
5969
5970 av[0] = group_name;
5971 call_args[0] = (char *)ldap_handle;
5972 call_args[1] = dn_path;
5973 call_args[2] = group_name;
5974 call_args[3] = (char *)(MOIRA_USERS | MOIRA_KERBEROS | MOIRA_STRINGS);
5975 call_args[4] = (char *)updateGroup;
5976 call_args[5] = MoiraId;
5977 call_args[6] = "0";
5978 call_args[7] = NULL;
5979 callback_rc = 0;
5980
5981 group_count = 0;
5982 group_base = NULL;
5983
5984 if (rc = mr_query("get_list_info", 1, av, group_create, call_args))
5985 {
5986 moira_disconnect();
5987 com_err(whoami, 0, "Unable to create list %s : %s", group_name,
5988 error_message(rc));
5989 return(rc);
5990 }
5991
5992 if (callback_rc)
5993 {
5994 moira_disconnect();
5995 com_err(whoami, 0, "Unable to create list %s", group_name);
5996 return(callback_rc);
5997 }
5998
5999 return(0);
6000}
6001
6002int populate_group(LDAP *ldap_handle, char *dn_path, char *group_name,
6003 char *group_ou, char *group_membership,
6004 int group_security_flag, char *MoiraId)
6005{
6006 char *av[3];
6007 char *call_args[7];
6008 char *pUserOu;
6009 LK_ENTRY *ptr;
6010 int rc;
6011 char member[512];
6012 char *s;
6013 char **members;
6014 int i = 0;
6015 int j = 0;
6016 int n = 0;
6017 char group_dn[512];
6018 LDAPMod *mods[20];
e8332ac3 6019 char *member_v[] = {NULL, NULL};
61a2844b 6020 char *save_argv[U_END];
e8332ac3 6021 char machine_ou[256];
6022 char NewMachineName[1024];
61a2844b 6023
6024 com_err(whoami, 0, "Populating group %s", group_name);
6025 av[0] = group_name;
6026 call_args[0] = (char *)ldap_handle;
6027 call_args[1] = dn_path;
6028 call_args[2] = group_name;
e8332ac3 6029 call_args[3] = (char *)(MOIRA_USERS | MOIRA_KERBEROS | MOIRA_STRINGS |
6030 MOIRA_MACHINE);
61a2844b 6031 call_args[4] = NULL;
6032 member_base = NULL;
6033
6034 if (rc = mr_query("get_end_members_of_list", 1, av,
6035 member_list_build, call_args))
6036 {
fe81e80b 6037 if(rc == MR_LIST)
6038 return(0);
6039
61a2844b 6040 com_err(whoami, 0, "Unable to populate list %s : %s",
6041 group_name, error_message(rc));
6042 return(3);
6043 }
6044
6045 members = (char **)malloc(sizeof(char *) * 2);
e8332ac3 6046
61a2844b 6047 if (member_base != NULL)
6048 {
6049 ptr = member_base;
6050
6051 while (ptr != NULL)
6052 {
6053 if (!strcasecmp(ptr->type, "LIST"))
6054 {
6055 ptr = ptr->next;
6056 continue;
6057 }
6058
e8332ac3 6059 if (!strcasecmp(ptr->type, "MACHINE") && !ProcessMachineContainer)
6060 {
6061 ptr = ptr->next;
6062 continue;
6063 }
6064
63d9f3c3 6065 if(!strcasecmp(ptr->type, "USER"))
61a2844b 6066 {
63d9f3c3 6067 if(!strcasecmp(ptr->member, PRODUCTION_PRINCIPAL) ||
6068 !strcasecmp(ptr->member, TEST_PRINCIPAL))
6069 {
6070 ptr = ptr->next;
6071 continue;
6072 }
6073
61a2844b 6074 if ((rc = check_user(ldap_handle, dn_path, ptr->member,
6075 "")) == AD_NO_USER_FOUND)
6076 {
6077 com_err(whoami, 0, "creating user %s", ptr->member);
6078
6079 av[0] = ptr->member;
6080 call_args[0] = (char *)ldap_handle;
6081 call_args[1] = dn_path;
6082 call_args[2] = "";
6083 call_args[3] = NULL;
6084 callback_rc = 0;
6085
6086 if (rc = mr_query("get_user_account_by_login", 1, av,
6087 save_query_info, save_argv))
6088 {
6089 com_err(whoami, 0, "Unable to create user %s "
6090 "while populating group %s.", ptr->member,
6091 group_name);
6092
6093 return(3);
6094 }
6095
6096 if (rc = user_create(U_END, save_argv, call_args))
6097 {
6098 com_err(whoami, 0, "Unable to create user %s "
6099 "while populating group %s.", ptr->member,
6100 group_name);
6101
6102 return(3);
6103 }
6104
6105 if (callback_rc)
6106 {
6107 com_err(whoami, 0, "Unable to create user %s "
6108 "while populating group %s", ptr->member,
6109 group_name);
6110
6111 return(3);
6112 }
6113 }
6114
6115 pUserOu = user_ou;
6116
6117 if(ActiveDirectory)
6118 {
6119 sprintf(member, "cn=%s,%s,%s", ptr->member, pUserOu,
6120 dn_path);
6121 }
6122 else
6123 {
6124 sprintf(member, "uid=%s,%s,%s", ptr->member, pUserOu,
6125 dn_path);
6126 }
6127
6128 }
6129 else if (!strcasecmp(ptr->type, "STRING"))
6130 {
6131 if (contact_create(ldap_handle, dn_path, ptr->member,
6132 contact_ou))
6133 return(3);
6134
6135 pUserOu = contact_ou;
6136 sprintf(member, "cn=%s,%s,%s", escape_string(ptr->member),
6137 pUserOu, dn_path);
6138 }
6139 else if (!strcasecmp(ptr->type, "KERBEROS"))
6140 {
6141 if (contact_create(ldap_handle, dn_path, ptr->member,
6142 kerberos_ou))
6143 return(3);
6144
6145 pUserOu = kerberos_ou;
6146 sprintf(member, "cn=%s,%s,%s", escape_string(ptr->member),
6147 pUserOu, dn_path);
6148 }
e8332ac3 6149 else if (!strcasecmp(ptr->type, "MACHINE"))
6150 {
6151 memset(machine_ou, '\0', sizeof(machine_ou));
6152 memset(NewMachineName, '\0', sizeof(NewMachineName));
6153
6154 if (!get_machine_ou(ldap_handle, dn_path, ptr->member,
6155 machine_ou, NewMachineName))
6156 {
6157 pUserOu = machine_ou;
6158 sprintf(member, "cn=%s,%s,%s", NewMachineName, pUserOu,
6159 dn_path);
6160 }
6161 else
6162 {
6163 ptr = ptr->next;
6164 continue;
6165 }
6166 }
61a2844b 6167
6168 if(i > 1)
6169 members = (char **)realloc(members, ((i + 2) * sizeof(char *)));
6170 members[i++] = strdup(member);
6171
6172 ptr = ptr->next;
6173 }
6174
6175 linklist_free(member_base);
6176 member_base = NULL;
6177 }
6178
6179 members[i] = NULL;
e8332ac3 6180
6181 sprintf(group_dn, "cn=%s,%s,%s", group_name, group_ou, dn_path);
6182
6183 if(GroupPopulateDelete)
6184 {
6185 n = 0;
6186 ADD_ATTR("member", member_v, LDAP_MOD_REPLACE);
6187 mods[n] = NULL;
6188
6189 if ((rc = ldap_modify_s(ldap_handle, group_dn,
6190 mods)) != LDAP_SUCCESS)
6191 {
6192 com_err(whoami, 0,
6193 "Unable to populate group membership for %s: %s",
6194 group_dn, ldap_err2string(rc));
6195 }
61a2844b 6196
e8332ac3 6197 for (i = 0; i < n; i++)
6198 free(mods[i]);
6199 }
6200
61a2844b 6201 n = 0;
6202 ADD_ATTR("member", members, LDAP_MOD_REPLACE);
6203 mods[n] = NULL;
e8332ac3 6204
61a2844b 6205 if ((rc = ldap_modify_s(ldap_handle, group_dn,
6206 mods)) != LDAP_SUCCESS)
6207 {
6208 com_err(whoami, 0,
6209 "Unable to populate group membership for %s: %s",
6210 group_dn, ldap_err2string(rc));
6211 }
6212
6213 for (i = 0; i < n; i++)
6214 free(mods[i]);
e8332ac3 6215
61a2844b 6216 free(members);
6217
6218 return(0);
6219}
6220
6221int process_group(LDAP *ldap_handle, char *dn_path, char *MoiraId,
6222 char *group_name, char *group_ou, char *group_membership,
6223 int group_security_flag, int type, char *maillist)
6224{
6225 char before_desc[512];
6226 char before_name[256];
6227 char before_group_ou[256];
6228 char before_group_membership[2];
6229 char distinguishedName[256];
6230 char ad_distinguishedName[256];
6231 char filter[128];
6232 char *attr_array[3];
6233 int before_security_flag;
6234 int group_count;
6235 int rc;
6236 LK_ENTRY *group_base;
6237 LK_ENTRY *ptr;
6238 char ou_both[512];
6239 char ou_security[512];
6240 char ou_distribution[512];
6241 char ou_neither[512];
6242 char group_dn[512];
6243
6244 memset(ad_distinguishedName, '\0', sizeof(ad_distinguishedName));
6245 sprintf(distinguishedName, "CN=%s,%s,%s", group_name, group_ou, dn_path);
6246
6247 memset(filter, '\0', sizeof(filter));
6248 group_base = NULL;
6249 group_count = 0;
6250
6251 if (rc = ad_get_group(ldap_handle, dn_path, group_name,
6252 "*", MoiraId,
6253 "samAccountName", &group_base,
6254 &group_count, filter))
6255 return(rc);
6256
6257 if (type == CHECK_GROUPS)
6258 {
6259 if (group_count == 1)
6260 {
6261 strcpy(group_dn, group_base->dn);
6262
6263 if (!strcasecmp(group_dn, distinguishedName))
6264 {
6265 linklist_free(group_base);
6266 return(0);
6267 }
6268 }
6269
6270 linklist_free(group_base);
6271
6272 if (group_count == 0)
6273 return(AD_NO_GROUPS_FOUND);
6274
6275 if (group_count == 1)
6276 return(AD_WRONG_GROUP_DN_FOUND);
6277
6278 return(AD_MULTIPLE_GROUPS_FOUND);
6279 }
6280
6281 if (group_count == 0)
6282 {
6283 return(AD_NO_GROUPS_FOUND);
6284 }
6285
6286 if (group_count > 1)
6287 {
6288 ptr = group_base;
6289
6290 strcpy(group_dn, ptr->dn);
6291
6292 while (ptr != NULL)
6293 {
6294 if (!strcasecmp(group_dn, ptr->value))
6295 break;
6296
6297 ptr = ptr->next;
6298 }
6299
6300 if (ptr == NULL)
6301 {
6302 com_err(whoami, 0, "%d groups with moira id = %s", group_count,
6303 MoiraId);
6304 ptr = group_base;
6305
6306 while (ptr != NULL)
6307 {
6308 com_err(whoami, 0, "%s with moira id = %s", ptr->value, MoiraId);
6309 ptr = ptr->next;
6310 }
6311
6312 linklist_free(group_base);
6313 return(AD_MULTIPLE_GROUPS_FOUND);
6314 }
6315
6316 ptr = group_base;
6317
6318 while (ptr != NULL)
6319 {
6320 strcpy(group_dn, ptr->dn);
6321
6322 if (strcasecmp(group_dn, ptr->value))
6323 rc = ldap_delete_s(ldap_handle, ptr->value);
6324
6325 ptr = ptr->next;
6326 }
6327
6328 linklist_free(group_base);
6329 memset(filter, '\0', sizeof(filter));
6330 group_base = NULL;
6331 group_count = 0;
6332
6333 if (rc = ad_get_group(ldap_handle, dn_path, group_name,
6334 "*", MoiraId,
6335 "samAccountName", &group_base,
6336 &group_count, filter))
6337 return(rc);
6338
6339 if (group_count == 0)
6340 return(AD_NO_GROUPS_FOUND);
6341
6342 if (group_count > 1)
6343 return(AD_MULTIPLE_GROUPS_FOUND);
6344 }
6345
6346 strcpy(ad_distinguishedName, group_base->dn);
6347 linklist_free(group_base);
6348 group_base = NULL;
6349 group_count = 0;
6350
6351 attr_array[0] = "sAMAccountName";
6352 attr_array[1] = NULL;
6353
6354 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6355 &group_base, &group_count,
6356 LDAP_SCOPE_SUBTREE)) != 0)
6357 {
6358 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
6359 MoiraId, ldap_err2string(rc));
6360 return(rc);
6361 }
6362
6363 sprintf(filter, "(sAMAccountName=%s)", group_base->value);
6364
6365 if (!strcasecmp(ad_distinguishedName, distinguishedName))
6366 {
6367 linklist_free(group_base);
6368 group_base = NULL;
6369 group_count = 0;
6370 return(0);
6371 }
6372
6373 linklist_free(group_base);
6374 group_base = NULL;
6375 group_count = 0;
6376 memset(ou_both, '\0', sizeof(ou_both));
6377 memset(ou_security, '\0', sizeof(ou_security));
6378 memset(ou_distribution, '\0', sizeof(ou_distribution));
6379 memset(ou_neither, '\0', sizeof(ou_neither));
6380 memset(before_name, '\0', sizeof(before_name));
6381 memset(before_desc, '\0', sizeof(before_desc));
6382 memset(before_group_membership, '\0', sizeof(before_group_membership));
6383
6384 attr_array[0] = "name";
6385 attr_array[1] = NULL;
6386
6387 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6388 &group_base, &group_count,
6389 LDAP_SCOPE_SUBTREE)) != 0)
6390 {
6391 com_err(whoami, 0, "Unable to get list name with MoiraId = %s: %s",
6392 MoiraId, ldap_err2string(rc));
6393 return(rc);
6394 }
6395
6396 strcpy(before_name, group_base->value);
6397 linklist_free(group_base);
6398 group_base = NULL;
6399 group_count = 0;
6400
6401 attr_array[0] = "description";
6402 attr_array[1] = NULL;
6403
6404 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6405 &group_base, &group_count,
6406 LDAP_SCOPE_SUBTREE)) != 0)
6407 {
6408 com_err(whoami, 0,
6409 "Unable to get list description with MoiraId = %s: %s",
6410 MoiraId, ldap_err2string(rc));
6411 return(rc);
6412 }
6413
6414 if (group_count != 0)
6415 {
6416 strcpy(before_desc, group_base->value);
6417 linklist_free(group_base);
6418 group_base = NULL;
6419 group_count = 0;
6420 }
6421
6422 change_to_lower_case(ad_distinguishedName);
6423 strcpy(ou_both, group_ou_both);
6424 change_to_lower_case(ou_both);
6425 strcpy(ou_security, group_ou_security);
6426 change_to_lower_case(ou_security);
6427 strcpy(ou_distribution, group_ou_distribution);
6428 change_to_lower_case(ou_distribution);
6429 strcpy(ou_neither, group_ou_neither);
6430 change_to_lower_case(ou_neither);
6431
6432 if (strstr(ad_distinguishedName, ou_both))
6433 {
6434 strcpy(before_group_ou, group_ou_both);
6435 before_group_membership[0] = 'B';
6436 before_security_flag = 1;
6437 }
6438 else if (strstr(ad_distinguishedName, ou_security))
6439 {
6440 strcpy(before_group_ou, group_ou_security);
6441 before_group_membership[0] = 'S';
6442 before_security_flag = 1;
6443 }
6444 else if (strstr(ad_distinguishedName, ou_distribution))
6445 {
6446 strcpy(before_group_ou, group_ou_distribution);
6447 before_group_membership[0] = 'D';
6448 before_security_flag = 0;
6449 }
6450 else if (strstr(ad_distinguishedName, ou_neither))
6451 {
6452 strcpy(before_group_ou, group_ou_neither);
6453 before_group_membership[0] = 'N';
6454 before_security_flag = 0;
6455 }
6456 else
6457 return(AD_NO_OU_FOUND);
6458
6459 rc = group_rename(ldap_handle, dn_path, before_name,
6460 before_group_membership,
6461 before_group_ou, before_security_flag, before_desc,
6462 group_name, group_membership, group_ou,
6463 group_security_flag,
6464 before_desc, MoiraId, filter, maillist);
6465
6466 return(rc);
6467}
6468
6469void change_to_lower_case(char *ptr)
6470{
6471 int i;
6472
6473 for (i = 0; i < (int)strlen(ptr); i++)
6474 {
6475 ptr[i] = tolower(ptr[i]);
6476 }
6477}
6478
6479int ad_get_group(LDAP *ldap_handle, char *dn_path,
6480 char *group_name, char *group_membership,
6481 char *MoiraId, char *attribute,
6482 LK_ENTRY **linklist_base, int *linklist_count,
6483 char *rFilter)
6484{
6485 LK_ENTRY *pPtr;
6486 char filter[128];
6487 char *attr_array[3];
6488 char *dn;
6489 int rc;
6490
6491 (*linklist_base) = NULL;
6492 (*linklist_count) = 0;
6493
6494 if (strlen(rFilter) != 0)
6495 {
6496 strcpy(filter, rFilter);
6497 attr_array[0] = attribute;
6498 attr_array[1] = NULL;
6499
6500 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6501 linklist_base, linklist_count,
6502 LDAP_SCOPE_SUBTREE)) != 0)
6503 {
6504 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
6505 MoiraId, ldap_err2string(rc));
6506 return(rc);
6507 }
6508
6509 if ((*linklist_count) == 1)
6510 {
6511 strcpy(rFilter, filter);
6512 return(0);
6513 }
6514 }
6515
6516 linklist_free((*linklist_base));
6517 (*linklist_base) = NULL;
6518 (*linklist_count) = 0;
6519
6520 if (strlen(MoiraId) != 0)
6521 {
6522 sprintf(filter, "(&(objectClass=group)(mitMoiraId=%s))", MoiraId);
6523
6524 attr_array[0] = attribute;
6525 attr_array[1] = NULL;
6526
6527 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6528 linklist_base, linklist_count,
6529 LDAP_SCOPE_SUBTREE)) != 0)
6530 {
6531 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
6532 MoiraId, ldap_err2string(rc));
6533 return(rc);
6534 }
6535 }
6536
6537 if ((*linklist_count) > 1)
6538 {
6539 com_err(whoami, 0, "multiple groups with mitMoiraId = %s", MoiraId);
6540 pPtr = (*linklist_base);
6541
6542 while (pPtr)
6543 {
6544 com_err(whoami, 0, "groups %s has mitMoiraId = %s", pPtr->value,
6545 MoiraId);
6546 pPtr = pPtr->next;
6547 }
6548
6549 linklist_free((*linklist_base));
6550 (*linklist_base) = NULL;
6551 (*linklist_count) = 0;
6552 }
6553
6554 if ((*linklist_count) == 1)
6555 {
6556
6557 pPtr = (*linklist_base);
6558 dn = strdup(pPtr->dn);
6559 dn += 3;
6560
6561 if (!memcmp(dn, group_name, strlen(group_name)))
6562 {
6563 strcpy(rFilter, filter);
6564 return(0);
6565 }
6566 }
6567
6568 linklist_free((*linklist_base));
6569 (*linklist_base) = NULL;
6570 (*linklist_count) = 0;
6571 sprintf(filter, "(sAMAccountName=%s%s)", group_name, group_suffix);
6572
6573 attr_array[0] = attribute;
6574 attr_array[1] = NULL;
6575
6576 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6577 linklist_base, linklist_count,
6578 LDAP_SCOPE_SUBTREE)) != 0)
6579 {
6580 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
6581 MoiraId, ldap_err2string(rc));
6582 return(rc);
6583 }
6584
6585 if ((*linklist_count) == 1)
6586 {
6587 strcpy(rFilter, filter);
6588 return(0);
6589 }
6590
6591 return(0);
6592}
6593
6594int check_user(LDAP *ldap_handle, char *dn_path, char *UserName, char *MoiraId)
6595{
6596 char filter[128];
6597 char *attr_array[3];
6598 char SamAccountName[64];
6599 int group_count;
6600 int rc;
6601 LK_ENTRY *group_base;
6602 LK_ENTRY *gPtr;
6603
6604 group_count = 0;
6605 group_base = NULL;
6606
6607 if (strlen(MoiraId) != 0)
6608 {
6609 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
6610
6611 attr_array[0] = "sAMAccountName";
6612 attr_array[1] = NULL;
6613 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6614 &group_base, &group_count,
6615 LDAP_SCOPE_SUBTREE)) != 0)
6616 {
6617 com_err(whoami, 0, "Unable to process user %s : %s",
6618 UserName, ldap_err2string(rc));
6619 return(rc);
6620 }
6621
6622 if (group_count > 1)
6623 {
6624 com_err(whoami, 0, "multiple users exist with MoiraId = %s",
6625 MoiraId);
6626 gPtr = group_base;
6627
6628 while (gPtr)
6629 {
6630 com_err(whoami, 0, "user %s exist with MoiraId = %s",
6631 gPtr->value, MoiraId);
6632 gPtr = gPtr->next;
6633 }
6634 }
6635 }
6636
6637 if (group_count != 1)
6638 {
6639 linklist_free(group_base);
6640 group_count = 0;
6641 group_base = NULL;
6642 sprintf(filter, "(sAMAccountName=%s)", UserName);
6643 attr_array[0] = "sAMAccountName";
6644 attr_array[1] = NULL;
6645
6646 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6647 &group_base, &group_count,
6648 LDAP_SCOPE_SUBTREE)) != 0)
6649 {
6650 com_err(whoami, 0, "Unable to process user %s : %s",
6651 UserName, ldap_err2string(rc));
6652 return(rc);
6653 }
6654 }
6655
6656 if (group_count != 1)
6657 {
6658 linklist_free(group_base);
6659 return(AD_NO_USER_FOUND);
6660 }
6661
6662 strcpy(SamAccountName, group_base->value);
6663 linklist_free(group_base);
6664 group_count = 0;
6665 rc = 0;
6666
6667 if (strcmp(SamAccountName, UserName))
6668 {
a20c63cf 6669 com_err(whoami, 0,
6670 "User object %s with MoiraId %s has mismatched usernames "
6671 "(LDAP username %s, Moira username %s)", SamAccountName,
6672 MoiraId, SamAccountName, UserName);
61a2844b 6673 }
6674
6675 return(0);
6676}
6677
6678void container_get_dn(char *src, char *dest)
6679{
6680 char *sPtr;
6681 char *array[20];
6682 char name[256];
6683 int n;
6684
6685 memset(array, '\0', 20 * sizeof(array[0]));
6686
6687 if (strlen(src) == 0)
6688 return;
6689
6690 strcpy(name, src);
6691 sPtr = name;
6692 n = 0;
6693 array[n] = name;
6694 ++n;
6695
6696 while (*sPtr)
6697 {
6698 if ((*sPtr) == '/')
6699 {
6700 (*sPtr) = '\0';
6701 ++sPtr;
6702 array[n] = sPtr;
6703 ++n;
6704 }
6705 else
6706 ++sPtr;
6707 }
6708
6709 strcpy(dest, "OU=");
6710
6711 while (n != 0)
6712 {
6713 strcat(dest, array[n-1]);
6714 --n;
6715 if (n > 0)
6716 {
6717 strcat(dest, ",OU=");
6718 }
6719 }
6720
6721 return;
6722}
6723
6724void container_get_name(char *src, char *dest)
6725{
6726 char *sPtr;
6727 char *dPtr;
6728
6729 if (strlen(src) == 0)
6730 return;
6731
6732 sPtr = src;
6733 dPtr = src;
6734
6735 while (*sPtr)
6736 {
6737 if ((*sPtr) == '/')
6738 {
6739 dPtr = sPtr;
6740 ++dPtr;
6741 }
6742 ++sPtr;
6743 }
6744
6745 strcpy(dest, dPtr);
6746 return;
6747}
6748
6749void container_check(LDAP *ldap_handle, char *dn_path, char *name)
6750{
6751 char cName[256];
6752 char *av[7];
6753 int i;
6754 int rc;
6755
6756 strcpy(cName, name);
6757
6758 for (i = 0; i < (int)strlen(cName); i++)
6759 {
6760 if (cName[i] == '/')
6761 {
6762 cName[i] = '\0';
6763 av[CONTAINER_NAME] = cName;
6764 av[CONTAINER_DESC] = "";
6765 av[CONTAINER_LOCATION] = "";
6766 av[CONTAINER_CONTACT] = "";
6767 av[CONTAINER_TYPE] = "";
6768 av[CONTAINER_ID] = "";
6769 av[CONTAINER_ROWID] = "";
6770 rc = container_create(ldap_handle, dn_path, 7, av);
6771
6772 if (rc == LDAP_SUCCESS)
6773 {
6774 com_err(whoami, 0, "container %s created without a mitMoiraId",
6775 cName);
6776 }
6777
6778 cName[i] = '/';
6779 }
6780 }
6781}
6782
6783int container_rename(LDAP *ldap_handle, char *dn_path, int beforec,
6784 char **before, int afterc, char **after)
6785{
6786 char dName[256];
6787 char cName[256];
6788 char new_cn[128];
6789 char new_dn_path[256];
6790 char temp[256];
6791 char distinguishedName[256];
6792 char *pPtr;
6793 int rc;
6794 int i;
6795
6796 memset(cName, '\0', sizeof(cName));
6797 container_get_name(after[CONTAINER_NAME], cName);
6798
6799 if (!check_container_name(cName))
6800 {
6801 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
6802 cName);
6803 return(AD_INVALID_NAME);
6804 }
6805
6806 memset(distinguishedName, '\0', sizeof(distinguishedName));
6807
6808 if (rc = container_get_distinguishedName(ldap_handle, dn_path,
6809 distinguishedName, beforec, before))
6810 return(rc);
6811
6812 if (strlen(distinguishedName) == 0)
6813 {
6814 rc = container_create(ldap_handle, dn_path, afterc, after);
6815 return(rc);
6816 }
6817
6818 strcpy(temp, after[CONTAINER_NAME]);
6819 pPtr = temp;
6820
6821 for (i = 0; i < (int)strlen(temp); i++)
6822 {
6823 if (temp[i] == '/')
6824 {
6825 pPtr = &temp[i];
6826 }
6827 }
6828
6829 (*pPtr) = '\0';
6830
6831 container_get_dn(temp, dName);
6832
6833 if (strlen(temp) != 0)
6834 sprintf(new_dn_path, "%s,%s", dName, dn_path);
6835 else
6836 sprintf(new_dn_path, "%s", dn_path);
6837
6838 sprintf(new_cn, "OU=%s", cName);
6839
6840 container_check(ldap_handle, dn_path, after[CONTAINER_NAME]);
6841
6842 if ((rc = ldap_rename_s(ldap_handle, distinguishedName, new_cn, new_dn_path,
6843 TRUE, NULL, NULL)) != LDAP_SUCCESS)
6844 {
6845 com_err(whoami, 0, "Unable to rename container from %s to %s : %s",
6846 before[CONTAINER_NAME], after[CONTAINER_NAME],
6847 ldap_err2string(rc));
6848 return(rc);
6849 }
6850
6851 memset(dName, '\0', sizeof(dName));
6852 container_get_dn(after[CONTAINER_NAME], dName);
6853 rc = container_adupdate(ldap_handle, dn_path, dName, "", afterc, after);
6854
6855 return(rc);
6856}
6857
6858int container_delete(LDAP *ldap_handle, char *dn_path, int count, char **av)
6859{
6860 char distinguishedName[256];
6861 int rc;
6862
6863 memset(distinguishedName, '\0', sizeof(distinguishedName));
6864
6865 if (rc = container_get_distinguishedName(ldap_handle, dn_path,
6866 distinguishedName, count, av))
6867 return(rc);
6868
6869 if (strlen(distinguishedName) == 0)
6870 return(0);
6871
6872 if ((rc = ldap_delete_s(ldap_handle, distinguishedName)) != LDAP_SUCCESS)
6873 {
6874 if (rc == LDAP_NOT_ALLOWED_ON_NONLEAF)
6875 container_move_objects(ldap_handle, dn_path, distinguishedName);
6876 else
c9ef9269 6877 com_err(whoami, 0, "Unable to delete container %s from directory : %s",
61a2844b 6878 av[CONTAINER_NAME], ldap_err2string(rc));
6879 }
6880
6881 return(rc);
6882}
6883
6884int container_create(LDAP *ldap_handle, char *dn_path, int count, char **av)
6885{
6886 char *attr_array[3];
6887 LK_ENTRY *group_base;
6888 int group_count;
6889 LDAPMod *mods[20];
6890 char *objectClass_v[] = {"top",
6891 "organizationalUnit",
6892 NULL};
6893
6894 char *ou_v[] = {NULL, NULL};
6895 char *name_v[] = {NULL, NULL};
6896 char *moiraId_v[] = {NULL, NULL};
6897 char *desc_v[] = {NULL, NULL};
6898 char *managedBy_v[] = {NULL, NULL};
6899 char dName[256];
6900 char cName[256];
6901 char managedByDN[256];
6902 char filter[256];
6903 char temp[256];
6904 int n;
6905 int i;
6906 int rc;
6907
6908 memset(filter, '\0', sizeof(filter));
6909 memset(dName, '\0', sizeof(dName));
6910 memset(cName, '\0', sizeof(cName));
6911 memset(managedByDN, '\0', sizeof(managedByDN));
6912 container_get_dn(av[CONTAINER_NAME], dName);
6913 container_get_name(av[CONTAINER_NAME], cName);
6914
6915 if ((strlen(cName) == 0) || (strlen(dName) == 0))
6916 {
6917 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
6918 cName);
6919 return(AD_INVALID_NAME);
6920 }
6921
6922 if (!check_container_name(cName))
6923 {
6924 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
6925 cName);
6926 return(AD_INVALID_NAME);
6927 }
6928
6929 n = 0;
6930 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
6931 name_v[0] = cName;
6932 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
6933 ou_v[0] = cName;
6934 ADD_ATTR("ou", ou_v, LDAP_MOD_ADD);
6935
6936 if (strlen(av[CONTAINER_ROWID]) != 0)
6937 {
6938 moiraId_v[0] = av[CONTAINER_ROWID];
6939 ADD_ATTR("mitMoiraId", moiraId_v, LDAP_MOD_ADD);
6940 }
6941
6942 if (strlen(av[CONTAINER_DESC]) != 0)
6943 {
6944 desc_v[0] = av[CONTAINER_DESC];
6945 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
6946 }
6947
6948 if ((strlen(av[CONTAINER_TYPE]) != 0) && (strlen(av[CONTAINER_ID]) != 0))
6949 {
6950 if (!strcasecmp(av[CONTAINER_TYPE], "KERBEROS"))
6951 {
6952 if (!contact_create(ldap_handle, dn_path, av[CONTAINER_ID],
6953 kerberos_ou))
6954 {
6955 sprintf(managedByDN, "CN=%s,%s,%s", av[CONTAINER_ID],
6956 kerberos_ou, dn_path);
6957 managedBy_v[0] = managedByDN;
6958 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_ADD);
6959 }
6960 }
6961 else
6962 {
6963 if (!strcasecmp(av[CONTAINER_TYPE], "USER"))
6964 {
6965 sprintf(filter, "(&(cn=%s)(&(objectCategory=person)"
6966 "(objectClass=user)))", av[CONTAINER_ID]);
6967 }
6968
6969 if (!strcasecmp(av[CONTAINER_TYPE], "LIST"))
6970 {
6971 sprintf(filter, "(&(objectClass=group)(cn=%s))",
6972 av[CONTAINER_ID]);
6973 }
6974
6975 if (strlen(filter) != 0)
6976 {
6977 attr_array[0] = "distinguishedName";
6978 attr_array[1] = NULL;
6979 group_count = 0;
6980 group_base = NULL;
6981 if ((rc = linklist_build(ldap_handle, dn_path, filter,
6982 attr_array,
6983 &group_base, &group_count,
6984 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
6985 {
6986 if (group_count == 1)
6987 {
6988 strcpy(managedByDN, group_base->value);
6989 managedBy_v[0] = managedByDN;
6990 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_ADD);
6991 }
6992 linklist_free(group_base);
6993 group_base = NULL;
6994 group_count = 0;
6995 }
6996 }
6997 }
6998 }
6999
7000 mods[n] = NULL;
7001
7002 sprintf(temp, "%s,%s", dName, dn_path);
7003 rc = ldap_add_ext_s(ldap_handle, temp, mods, NULL, NULL);
7004
7005 for (i = 0; i < n; i++)
7006 free(mods[i]);
7007
7008 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
7009 {
7010 com_err(whoami, 0, "Unable to create container %s : %s",
7011 cName, ldap_err2string(rc));
7012 return(rc);
7013 }
7014
7015 if (rc == LDAP_ALREADY_EXISTS)
7016 {
7017 if (strlen(av[CONTAINER_ROWID]) != 0)
7018 rc = container_adupdate(ldap_handle, dn_path, dName, "", count, av);
7019 }
7020
7021 return(rc);
7022}
7023
7024int container_update(LDAP *ldap_handle, char *dn_path, int beforec,
7025 char **before, int afterc, char **after)
7026{
7027 char distinguishedName[256];
7028 int rc;
7029
7030 memset(distinguishedName, '\0', sizeof(distinguishedName));
7031
7032 if (rc = container_get_distinguishedName(ldap_handle, dn_path,
7033 distinguishedName, afterc, after))
7034 return(rc);
7035
7036 if (strlen(distinguishedName) == 0)
7037 {
7038 rc = container_create(ldap_handle, dn_path, afterc, after);
7039 return(rc);
7040 }
7041
7042 container_check(ldap_handle, dn_path, after[CONTAINER_NAME]);
7043 rc = container_adupdate(ldap_handle, dn_path, "", distinguishedName, afterc,
7044 after);
7045
7046 return(rc);
7047}
7048
7049int container_get_distinguishedName(LDAP *ldap_handle, char *dn_path,
7050 char *distinguishedName, int count,
7051 char **av)
7052{
7053 char *attr_array[3];
7054 LK_ENTRY *group_base;
7055 int group_count;
7056 char dName[256];
7057 char cName[256];
7058 char filter[512];
7059 int rc;
7060
7061 memset(filter, '\0', sizeof(filter));
7062 memset(dName, '\0', sizeof(dName));
7063 memset(cName, '\0', sizeof(cName));
7064 container_get_dn(av[CONTAINER_NAME], dName);
7065 container_get_name(av[CONTAINER_NAME], cName);
7066
7067 if (strlen(dName) == 0)
7068 {
7069 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
7070 av[CONTAINER_NAME]);
7071 return(AD_INVALID_NAME);
7072 }
7073
7074 if (!check_container_name(cName))
7075 {
7076 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
7077 cName);
7078 return(AD_INVALID_NAME);
7079 }
7080
7081 sprintf(filter, "(&(objectClass=organizationalUnit)(mitMoiraId=%s))",
7082 av[CONTAINER_ROWID]);
7083 attr_array[0] = "distinguishedName";
7084 attr_array[1] = NULL;
7085 group_count = 0;
7086 group_base = NULL;
7087
7088 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
7089 &group_base, &group_count,
7090 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
7091 {
7092 if (group_count == 1)
7093 {
7094 strcpy(distinguishedName, group_base->value);
7095 }
7096
7097 linklist_free(group_base);
7098 group_base = NULL;
7099 group_count = 0;
7100 }
7101
7102 if (strlen(distinguishedName) == 0)
7103 {
7104 sprintf(filter, "(&(objectClass=organizationalUnit)"
7105 "(distinguishedName=%s,%s))", dName, dn_path);
7106 attr_array[0] = "distinguishedName";
7107 attr_array[1] = NULL;
7108 group_count = 0;
7109 group_base = NULL;
7110
7111 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
7112 &group_base, &group_count,
7113 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
7114 {
7115 if (group_count == 1)
7116 {
7117 strcpy(distinguishedName, group_base->value);
7118 }
7119
7120 linklist_free(group_base);
7121 group_base = NULL;
7122 group_count = 0;
7123 }
7124 }
7125
7126 return(0);
7127}
7128
7129int container_adupdate(LDAP *ldap_handle, char *dn_path, char *dName,
7130 char *distinguishedName, int count, char **av)
7131{
7132 char *attr_array[5];
7133 LK_ENTRY *group_base;
7134 LK_ENTRY *pPtr;
7135 LDAPMod *mods[20];
7136 int group_count;
7137 char filter[512];
7138 char *moiraId_v[] = {NULL, NULL};
7139 char *desc_v[] = {NULL, NULL};
7140 char *managedBy_v[] = {NULL, NULL};
7141 char managedByDN[256];
7142 char moiraId[64];
7143 char desc[256];
7144 char ad_path[512];
7145 int rc;
7146 int i;
7147 int n;
7148
7149
7150 strcpy(ad_path, distinguishedName);
7151
7152 if (strlen(dName) != 0)
7153 sprintf(ad_path, "%s,%s", dName, dn_path);
7154
7155 sprintf(filter, "(&(objectClass=organizationalUnit)(distinguishedName=%s))",
7156 ad_path);
7157
7158 if (strlen(av[CONTAINER_ID]) != 0)
7159 sprintf(filter, "(&(objectClass=organizationalUnit)(mitMoiraId=%s))",
7160 av[CONTAINER_ROWID]);
7161
7162 attr_array[0] = "mitMoiraId";
7163 attr_array[1] = "description";
7164 attr_array[2] = "managedBy";
7165 attr_array[3] = NULL;
7166 group_count = 0;
7167 group_base = NULL;
7168
7169 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
7170 &group_base, &group_count,
7171 LDAP_SCOPE_SUBTREE)) != LDAP_SUCCESS)
7172 {
7173 com_err(whoami, 0, "Unable to retreive container info for %s : %s",
7174 av[CONTAINER_NAME], ldap_err2string(rc));
7175 return(rc);
7176 }
7177
7178 memset(managedByDN, '\0', sizeof(managedByDN));
7179 memset(moiraId, '\0', sizeof(moiraId));
7180 memset(desc, '\0', sizeof(desc));
7181 pPtr = group_base;
7182
7183 while (pPtr)
7184 {
7185 if (!strcasecmp(pPtr->attribute, "description"))
7186 strcpy(desc, pPtr->value);
7187 else if (!strcasecmp(pPtr->attribute, "managedBy"))
7188 strcpy(managedByDN, pPtr->value);
7189 else if (!strcasecmp(pPtr->attribute, "mitMoiraId"))
7190 strcpy(moiraId, pPtr->value);
7191 pPtr = pPtr->next;
7192 }
7193
7194 linklist_free(group_base);
7195 group_base = NULL;
7196 group_count = 0;
7197
7198 n = 0;
7199 if (strlen(av[CONTAINER_ROWID]) != 0)
7200 {
7201 moiraId_v[0] = av[CONTAINER_ROWID];
7202 ADD_ATTR("mitMoiraId", moiraId_v, LDAP_MOD_REPLACE);
7203 }
7204
7205 if (strlen(av[CONTAINER_DESC]) != 0)
7206 {
7207 attribute_update(ldap_handle, ad_path, av[CONTAINER_DESC], "description",
7208 dName);
7209 }
7210 else
7211 {
7212 if (strlen(desc) != 0)
7213 {
7214 attribute_update(ldap_handle, ad_path, "", "description", dName);
7215 }
7216 }
7217
7218 if ((strlen(av[CONTAINER_TYPE]) != 0) && (strlen(av[CONTAINER_ID]) != 0))
7219 {
7220 if (!strcasecmp(av[CONTAINER_TYPE], "KERBEROS"))
7221 {
7222 if (!contact_create(ldap_handle, dn_path, av[CONTAINER_ID],
7223 kerberos_ou))
7224 {
7225 sprintf(managedByDN, "CN=%s,%s,%s", av[CONTAINER_ID],
7226 kerberos_ou, dn_path);
7227 managedBy_v[0] = managedByDN;
7228 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_REPLACE);
7229 }
7230 else
7231 {
7232 if (strlen(managedByDN) != 0)
7233 {
7234 attribute_update(ldap_handle, ad_path, "", "managedBy",
7235 dName);
7236 }
7237 }
7238 }
7239 else
7240 {
7241 memset(filter, '\0', sizeof(filter));
7242
7243 if (!strcasecmp(av[CONTAINER_TYPE], "USER"))
7244 {
7245 sprintf(filter, "(&(cn=%s)(&(objectCategory=person)"
7246 "(objectClass=user)))", av[CONTAINER_ID]);
7247 }
7248
7249 if (!strcasecmp(av[CONTAINER_TYPE], "LIST"))
7250 {
7251 sprintf(filter, "(&(objectClass=group)(cn=%s))",
7252 av[CONTAINER_ID]);
7253 }
7254
7255 if (strlen(filter) != 0)
7256 {
7257 attr_array[0] = "distinguishedName";
7258 attr_array[1] = NULL;
7259 group_count = 0;
7260 group_base = NULL;
7261 if ((rc = linklist_build(ldap_handle, dn_path, filter,
7262 attr_array, &group_base, &group_count,
7263 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
7264 {
7265 if (group_count == 1)
7266 {
7267 strcpy(managedByDN, group_base->value);
7268 managedBy_v[0] = managedByDN;
7269 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_REPLACE);
7270 }
7271 else
7272 {
7273 if (strlen(managedByDN) != 0)
7274 {
7275 attribute_update(ldap_handle, ad_path, "",
7276 "managedBy", dName);
7277 }
7278 }
7279
7280 linklist_free(group_base);
7281 group_base = NULL;
7282 group_count = 0;
7283 }
7284 }
7285 else
7286 {
7287 if (strlen(managedByDN) != 0)
7288 {
7289 attribute_update(ldap_handle, ad_path, "", "managedBy",
7290 dName);
7291 }
7292 }
7293 }
7294 }
7295
7296 mods[n] = NULL;
7297
7298 if (n == 0)
7299 return(LDAP_SUCCESS);
7300
7301 rc = ldap_modify_s(ldap_handle, ad_path, mods);
7302
7303 for (i = 0; i < n; i++)
7304 free(mods[i]);
7305
7306 if (rc != LDAP_SUCCESS)
7307 {
7308 com_err(whoami, 0, "Unable to modify container info for %s : %s",
7309 av[CONTAINER_NAME], ldap_err2string(rc));
7310 return(rc);
7311 }
7312
7313 return(rc);
7314}
7315
7316int container_move_objects(LDAP *ldap_handle, char *dn_path, char *dName)
7317{
7318 char *attr_array[3];
7319 LK_ENTRY *group_base;
7320 LK_ENTRY *pPtr;
7321 int group_count;
7322 char filter[512];
7323 char new_cn[128];
7324 char temp[256];
7325 int rc;
7326 int NumberOfEntries = 10;
7327 int i;
7328 int count;
7329
7330 rc = ldap_set_option(ldap_handle, LDAP_OPT_SIZELIMIT, &NumberOfEntries);
7331
7332 for (i = 0; i < 3; i++)
7333 {
7334 memset(filter, '\0', sizeof(filter));
7335
7336 if (i == 0)
7337 {
7338 strcpy(filter, "(!(|(objectClass=computer)"
7339 "(objectClass=organizationalUnit)))");
7340 attr_array[0] = "cn";
7341 attr_array[1] = NULL;
7342 }
7343 else if (i == 1)
7344 {
7345 strcpy(filter, "(objectClass=computer)");
7346 attr_array[0] = "cn";
7347 attr_array[1] = NULL;
7348 }
7349 else
7350 {
7351 strcpy(filter, "(objectClass=organizationalUnit)");
7352 attr_array[0] = "ou";
7353 attr_array[1] = NULL;
7354 }
7355
7356 while (1)
7357 {
7358 if ((rc = linklist_build(ldap_handle, dName, filter, attr_array,
7359 &group_base, &group_count,
7360 LDAP_SCOPE_SUBTREE)) != LDAP_SUCCESS)
7361 {
7362 break;
7363 }
7364
7365 if (group_count == 0)
7366 break;
7367
7368 pPtr = group_base;
7369
7370 while(pPtr)
7371 {
7372 if (!strcasecmp(pPtr->attribute, "cn"))
7373 {
7374 sprintf(new_cn, "cn=%s", pPtr->value);
7375 if (i == 0)
7376 sprintf(temp, "%s,%s", orphans_other_ou, dn_path);
7377 if (i == 1)
7378 sprintf(temp, "%s,%s", orphans_machines_ou, dn_path);
7379 count = 1;
7380
7381 while (1)
7382 {
7383 rc = ldap_rename_s(ldap_handle, pPtr->dn, new_cn, temp,
7384 TRUE, NULL, NULL);
7385 if (rc == LDAP_ALREADY_EXISTS)
7386 {
7387 sprintf(new_cn, "cn=%s_%d", pPtr->value, count);
7388 ++count;
7389 }
7390 else
7391 break;
7392 }
7393 }
7394 else if (!strcasecmp(pPtr->attribute, "ou"))
7395 {
7396 rc = ldap_delete_s(ldap_handle, pPtr->dn);
7397 }
7398
7399 pPtr = pPtr->next;
7400 }
7401
7402 linklist_free(group_base);
7403 group_base = NULL;
7404 group_count = 0;
7405 }
7406 }
7407
7408 return(0);
7409}
7410
7411int get_machine_ou(LDAP *ldap_handle, char *dn_path, char *member,
7412 char *machine_ou, char *NewMachineName)
7413{
7414 LK_ENTRY *group_base;
7415 int group_count;
7416 int i;
7417 char filter[128];
7418 char *attr_array[3];
7419 char cn[256];
7420 char dn[256];
7421 char temp[256];
7422 char *pPtr;
7423 int rc;
7424
7425 strcpy(NewMachineName, member);
7426 rc = moira_connect();
7427 rc = GetMachineName(NewMachineName);
7428 moira_disconnect();
7429
7430 if (strlen(NewMachineName) == 0)
7431 {
7432 com_err(whoami, 0, "Unable to find alais for machine %s in Moira",
7433 member);
7434 return(1);
7435 }
7436
7437 pPtr = NULL;
7438 pPtr = strchr(NewMachineName, '.');
7439
7440 if (pPtr != NULL)
7441 (*pPtr) = '\0';
7442
7443 group_base = NULL;
7444 group_count = 0;
7445 sprintf(filter, "(sAMAccountName=%s$)", NewMachineName);
7446 attr_array[0] = "cn";
7447 attr_array[1] = NULL;
7448 sprintf(temp, "%s", dn_path);
7449
7450 if ((rc = linklist_build(ldap_handle, temp, filter, attr_array,
7451 &group_base, &group_count,
7452 LDAP_SCOPE_SUBTREE)) != 0)
7453 {
7454 com_err(whoami, 0, "Unable to process machine %s : %s",
7455 member, ldap_err2string(rc));
7456 return(1);
7457 }
7458
7459 if (group_count != 1)
7460 {
61a2844b 7461 return(1);
7462 }
7463
7464 strcpy(dn, group_base->dn);
7465 strcpy(cn, group_base->value);
7466
7467 for (i = 0; i < (int)strlen(dn); i++)
7468 dn[i] = tolower(dn[i]);
7469
7470 for (i = 0; i < (int)strlen(cn); i++)
7471 cn[i] = tolower(cn[i]);
7472
7473 linklist_free(group_base);
7474 pPtr = NULL;
7475 pPtr = strstr(dn, cn);
7476
7477 if (pPtr == NULL)
7478 {
7479 com_err(whoami, 0, "Unable to process machine %s",
7480 member);
7481 return(1);
7482 }
7483
7484 pPtr += strlen(cn) + 1;
7485 strcpy(machine_ou, pPtr);
7486 pPtr = NULL;
7487 pPtr = strstr(machine_ou, "dc=");
7488
7489 if (pPtr == NULL)
7490 {
7491 com_err(whoami, 0, "Unable to process machine %s",
7492 member);
7493 return(1);
7494 }
7495
7496 --pPtr;
7497 (*pPtr) = '\0';
7498
7499 return(0);
7500}
7501
7502int machine_move_to_ou(LDAP *ldap_handle, char * dn_path,
7503 char *MoiraMachineName, char *DestinationOu)
7504{
7505 char NewCn[128];
7506 char OldDn[512];
7507 char MachineName[128];
7508 char filter[128];
7509 char *attr_array[3];
7510 char NewOu[256];
7511 char *cPtr = NULL;
7512 int group_count;
7513 long rc;
7514 LK_ENTRY *group_base;
7515
7516 group_count = 0;
7517 group_base = NULL;
7518
7519 strcpy(MachineName, MoiraMachineName);
7520 rc = GetMachineName(MachineName);
7521
7522 if (strlen(MachineName) == 0)
7523 {
7524 com_err(whoami, 0, "Unable to find alais for machine %s in Moira",
7525 MoiraMachineName);
7526 return(1);
7527 }
7528
7529 cPtr = strchr(MachineName, '.');
7530
7531 if (cPtr != NULL)
7532 (*cPtr) = '\0';
7533
7534 sprintf(filter, "(sAMAccountName=%s$)", MachineName);
7535 attr_array[0] = "sAMAccountName";
7536 attr_array[1] = NULL;
7537
7538 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
7539 &group_base,
7540 &group_count, LDAP_SCOPE_SUBTREE)) != 0)
7541 {
7542 com_err(whoami, 0, "Unable to process machine %s : %s",
7543 MoiraMachineName, ldap_err2string(rc));
7544 return(1);
7545 }
7546
7547 if (group_count == 1)
7548 strcpy(OldDn, group_base->dn);
7549
7550 linklist_free(group_base);
7551 group_base = NULL;
7552
7553 if (group_count != 1)
7554 {
c9ef9269 7555 com_err(whoami, 0, "Unable to find machine %s in directory: %s",
61a2844b 7556 MoiraMachineName);
7557 return(1);
7558 }
7559
7560 sprintf(NewOu, "%s,%s", DestinationOu, dn_path);
7561 cPtr = strchr(OldDn, ',');
7562
7563 if (cPtr != NULL)
7564 {
7565 ++cPtr;
7566 if (!strcasecmp(cPtr, NewOu))
7567 return(0);
7568 }
7569
7570 sprintf(NewCn, "CN=%s", MachineName);
7571 rc = ldap_rename_s(ldap_handle, OldDn, NewCn, NewOu, TRUE, NULL, NULL);
7572
7573 return(rc);
7574}
7575
7576int machine_check(LDAP *ldap_handle, char *dn_path, char *machine_name)
7577{
7578 char Name[128];
7579 char *pPtr;
7580 int rc;
7581
7582 memset(Name, '\0', sizeof(Name));
7583 strcpy(Name, machine_name);
7584 pPtr = NULL;
7585 pPtr = strchr(Name, '.');
7586
7587 if (pPtr != NULL)
7588 (*pPtr) = '\0';
7589
7590 strcat(Name, "$");
7591 return(!(rc = checkADname(ldap_handle, dn_path, Name)));
7592}
7593
7594int machine_get_moira_container(LDAP *ldap_handle, char *dn_path,
7595 char *machine_name, char *container_name)
7596{
7597 int rc;
7598 char *av[2];
7599 char *call_args[2];
7600
7601 av[0] = machine_name;
7602 call_args[0] = (char *)container_name;
7603 rc = mr_query("get_machine_to_container_map", 1, av,
7604 machine_GetMoiraContainer, call_args);
7605 return(rc);
7606}
7607
7608int machine_GetMoiraContainer(int ac, char **av, void *ptr)
7609{
7610 char **call_args;
7611
7612 call_args = ptr;
7613 strcpy(call_args[0], av[1]);
7614 return(0);
7615}
7616
7617int Moira_container_group_create(char **after)
7618{
7619 long rc;
7620 char GroupName[64];
7621 char *argv[20];
7622
7623 memset(GroupName, '\0', sizeof(GroupName));
7624 rc = Moira_groupname_create(GroupName, after[CONTAINER_NAME],
7625 after[CONTAINER_ROWID]);
7626 if (rc)
7627 return rc;
7628
7629 argv[L_NAME] = GroupName;
7630 argv[L_ACTIVE] = "1";
7631 argv[L_PUBLIC] = "0";
7632 argv[L_HIDDEN] = "0";
7633 argv[L_MAILLIST] = "0";
7634 argv[L_GROUP] = "1";
7635 argv[L_GID] = UNIQUE_GID;
7636 argv[L_NFSGROUP] = "0";
7637 argv[L_MAILMAN] = "0";
7638 argv[L_MAILMAN_SERVER] = "[NONE]";
7639 argv[L_DESC] = "auto created container group";
7640 argv[L_ACE_TYPE] = "USER";
7641 argv[L_MEMACE_TYPE] = "USER";
7642 argv[L_ACE_NAME] = "sms";
7643 argv[L_MEMACE_NAME] = "sms";
7644
7645 if (rc = mr_query("add_list", 15, argv, NULL, NULL))
7646 {
7647 com_err(whoami, 0,
7648 "Unable to create container group %s for container %s: %s",
7649 GroupName, after[CONTAINER_NAME], error_message(rc));
7650 }
7651
7652 Moira_setContainerGroup(after[CONTAINER_NAME], GroupName);
7653 Moira_addGroupToParent(after[CONTAINER_NAME], GroupName);
7654
7655 return(rc);
7656}
7657
7658int Moira_container_group_update(char **before, char **after)
7659{
7660 long rc;
7661 char BeforeGroupName[64];
7662 char AfterGroupName[64];
7663 char *argv[20];
7664
7665 if (!strcasecmp(after[CONTAINER_NAME], before[CONTAINER_NAME]))
7666 return(0);
7667
7668 memset(BeforeGroupName, '\0', sizeof(BeforeGroupName));
7669 Moira_getGroupName(after[CONTAINER_NAME], BeforeGroupName, 0);
7670 if (strlen(BeforeGroupName) == 0)
7671 return(0);
7672
7673 memset(AfterGroupName, '\0', sizeof(AfterGroupName));
7674 rc = Moira_groupname_create(AfterGroupName, after[CONTAINER_NAME],
7675 after[CONTAINER_ROWID]);
7676 if (rc)
7677 return rc;
7678
7679 if (strcasecmp(BeforeGroupName, AfterGroupName))
7680 {
7681 argv[L_NAME] = BeforeGroupName;
7682 argv[L_NAME + 1] = AfterGroupName;
7683 argv[L_ACTIVE + 1] = "1";
7684 argv[L_PUBLIC + 1] = "0";
7685 argv[L_HIDDEN + 1] = "0";
7686 argv[L_MAILLIST + 1] = "0";
7687 argv[L_GROUP + 1] = "1";
7688 argv[L_GID + 1] = UNIQUE_GID;
7689 argv[L_NFSGROUP + 1] = "0";
7690 argv[L_MAILMAN + 1] = "0";
7691 argv[L_MAILMAN_SERVER + 1] = "[NONE]";
7692 argv[L_DESC + 1] = "auto created container group";
7693 argv[L_ACE_TYPE + 1] = "USER";
7694 argv[L_MEMACE_TYPE + 1] = "USER";
7695 argv[L_ACE_NAME + 1] = "sms";
7696 argv[L_MEMACE_NAME + 1] = "sms";
7697
7698 if (rc = mr_query("update_list", 16, argv, NULL, NULL))
7699 {
7700 com_err(whoami, 0,
7701 "Unable to rename container group from %s to %s: %s",
7702 BeforeGroupName, AfterGroupName, error_message(rc));
7703 }
7704 }
7705
7706 return(rc);
7707}
7708
7709int Moira_container_group_delete(char **before)
7710{
7711 long rc = 0;
7712 char *argv[13];
7713 char GroupName[64];
7714 char ParentGroupName[64];
7715
7716 memset(ParentGroupName, '\0', sizeof(ParentGroupName));
7717 Moira_getGroupName(before[CONTAINER_NAME], ParentGroupName, 1);
7718
7719 memset(GroupName, '\0', sizeof(GroupName));
7720
7721 if (strcmp(before[CONTAINER_GROUP_NAME], "[none]"))
7722 strcpy(GroupName, before[CONTAINER_GROUP_NAME]);
7723
7724 if ((strlen(ParentGroupName) != 0) && (strlen(GroupName) != 0))
7725 {
7726 argv[0] = ParentGroupName;
7727 argv[1] = "LIST";
7728 argv[2] = GroupName;
7729
7730 if (rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL))
7731 {
7732 com_err(whoami, 0,
7733 "Unable to delete container group %s from list: %s",
7734 GroupName, ParentGroupName, error_message(rc));
7735 }
7736 }
7737
7738 if (strlen(GroupName) != 0)
7739 {
7740 argv[0] = GroupName;
7741
7742 if (rc = mr_query("delete_list", 1, argv, NULL, NULL))
7743 {
7744 com_err(whoami, 0, "Unable to delete container group %s : %s",
7745 GroupName, error_message(rc));
7746 }
7747 }
7748
7749 return(rc);
7750}
7751
7752int Moira_groupname_create(char *GroupName, char *ContainerName,
7753 char *ContainerRowID)
7754{
7755 char *ptr;
7756 char *ptr1;
7757 char temp[64];
7758 char newGroupName[64];
7759 char tempGroupName[64];
7760 char tempgname[64];
7761 char *argv[1];
7762 int i;
7763 long rc;
7764
7765 strcpy(temp, ContainerName);
7766
7767 ptr1 = strrchr(temp, '/');
7768
7769 if (ptr1 != NULL)
7770 {
7771 *ptr1 = '\0';
7772 ptr = ++ptr1;
7773 ptr1 = strrchr(temp, '/');
7774
7775 if (ptr1 != NULL)
7776 {
7777 sprintf(tempgname, "%s-%s", ++ptr1, ptr);
7778 }
7779 else
7780 strcpy(tempgname, ptr);
7781 }
7782 else
7783 strcpy(tempgname, temp);
7784
7785 if (strlen(tempgname) > 25)
7786 tempgname[25] ='\0';
7787
7788 sprintf(newGroupName, "cnt-%s", tempgname);
7789
7790 /* change everything to lower case */
7791 ptr = newGroupName;
7792
7793 while (*ptr)
7794 {
7795 if (isupper(*ptr))
7796 *ptr = tolower(*ptr);
7797
7798 if (*ptr == ' ')
7799 *ptr = '-';
7800
7801 ptr++;
7802 }
7803
7804 strcpy(tempGroupName, newGroupName);
7805 i = (int)'0';
7806
7807 /* append 0-9 then a-z if a duplicate is found */
7808 while(1)
7809 {
7810 argv[0] = newGroupName;
7811
7812 if (rc = mr_query("get_list_info", 1, argv, NULL, NULL))
7813 {
7814 if (rc == MR_NO_MATCH)
7815 break;
7816 com_err(whoami, 0, "Moira error while creating group name for "
7817 "container %s : %s", ContainerName, error_message(rc));
7818 return rc;
7819 }
7820
7821 sprintf(newGroupName, "%s-%c", tempGroupName, i);
7822
7823 if (i == (int)'z')
7824 {
7825 com_err(whoami, 0, "Unable to find a unique group name for "
7826 "container %s: too many duplicate container names",
7827 ContainerName);
7828 return 1;
7829 }
7830
7831 if (i == '9')
7832 i = 'a';
7833 else
7834 i++;
7835 }
7836
7837 strcpy(GroupName, newGroupName);
7838 return(0);
7839}
7840
7841int Moira_setContainerGroup(char *origContainerName, char *GroupName)
7842{
7843 long rc;
7844 char *argv[3];
7845
7846 argv[0] = origContainerName;
7847 argv[1] = GroupName;
7848
7849 if ((rc = mr_query("set_container_list", 2, argv, NULL, NULL)))
7850 {
7851 com_err(whoami, 0,
7852 "Unable to set container group %s in container %s: %s",
7853 GroupName, origContainerName, error_message(rc));
7854 }
7855
7856 return(0);
7857}
7858
7859int Moira_addGroupToParent(char *origContainerName, char *GroupName)
7860 {
7861 char ContainerName[64];
7862 char ParentGroupName[64];
7863 char *argv[3];
7864 long rc;
7865
7866 strcpy(ContainerName, origContainerName);
7867
7868 Moira_getGroupName(ContainerName, ParentGroupName, 1);
7869
7870 /* top-level container */
7871 if (strlen(ParentGroupName) == 0)
7872 return(0);
7873
7874 argv[0] = ParentGroupName;
7875 argv[1] = "LIST";
7876 argv[2] = GroupName;
7877
7878 if ((rc = mr_query("add_member_to_list", 3, argv, NULL, NULL)))
7879 {
7880 com_err(whoami, 0,
7881 "Unable to add container group %s to parent group %s: %s",
7882 GroupName, ParentGroupName, error_message(rc));
7883 }
7884
7885 return(0);
7886 }
7887
7888int Moira_getContainerGroup(int ac, char **av, void *ptr)
7889{
7890 char **call_args;
7891
7892 call_args = ptr;
7893 strcpy(call_args[0], av[1]);
7894
7895 return(0);
7896}
7897
7898int Moira_getGroupName(char *origContainerName, char *GroupName,
7899 int ParentFlag)
7900{
7901 char ContainerName[64];
7902 char *argv[3];
7903 char *call_args[3];
7904 char *ptr;
7905 long rc;
7906
7907 strcpy(ContainerName, origContainerName);
7908
7909 if (ParentFlag)
7910 {
7911 ptr = strrchr(ContainerName, '/');
7912
7913 if (ptr != NULL)
7914 (*ptr) = '\0';
7915 else
7916 return(0);
7917 }
7918
7919 argv[0] = ContainerName;
7920 argv[1] = NULL;
7921 call_args[0] = GroupName;
7922 call_args[1] = NULL;
7923
7924 if (!(rc = mr_query("get_container_list", 1, argv, Moira_getContainerGroup,
7925 call_args)))
7926 {
7927 if (strlen(GroupName) != 0)
7928 return(0);
7929 }
7930
7931 if (rc)
7932 com_err(whoami, 0, "Unable to get container group from container %s: %s",
7933 ContainerName, error_message(rc));
7934 else
7935 com_err(whoami, 0, "Unable to get container group from container %s",
7936 ContainerName);
7937
7938 return(0);
7939}
7940
7941int Moira_process_machine_container_group(char *MachineName, char* GroupName,
7942 int DeleteMachine)
7943{
7944 char *argv[3];
7945 long rc;
7946
7947 if (strcmp(GroupName, "[none]") == 0)
7948 return 0;
7949
7950 argv[0] = GroupName;
7951 argv[1] = "MACHINE";
7952 argv[2] = MachineName;
7953
7954 if (!DeleteMachine)
7955 rc = mr_query("add_member_to_list", 3, argv, NULL, NULL);
7956 else
7957 rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL);
7958
7959 if (rc)
7960 {
7961 com_err(whoami, 0, "Unable to add machine %s to container group%s: %s",
7962 MachineName, GroupName, error_message(rc));
7963 }
7964
7965 return(0);
7966}
7967
7968int GetMachineName(char *MachineName)
7969{
7970 char *args[2];
7971 char NewMachineName[1024];
7972 char *szDot;
7973 int rc = 0;
7974 int i;
7975 DWORD dwLen = 0;
7976 char *call_args[2];
7977
7978 // If the address happens to be in the top-level MIT domain, great!
7979 strcpy(NewMachineName, MachineName);
7980
7981 for (i = 0; i < (int)strlen(NewMachineName); i++)
7982 NewMachineName[i] = toupper(NewMachineName[i]);
7983
7984 szDot = strchr(NewMachineName,'.');
7985
7986 if ((szDot) && (!strcasecmp(szDot+1, DOMAIN_SUFFIX)))
7987 {
7988 return(0);
7989 }
7990
7991 // If not, see if it has a Moira alias in the top-level MIT domain.
7992 memset(NewMachineName, '\0', sizeof(NewMachineName));
7993 args[0] = "*";
7994 args[1] = MachineName;
7995 call_args[0] = NewMachineName;
7996 call_args[1] = NULL;
7997
7998 if (rc = mr_query("get_hostalias", 2, args, ProcessMachineName, call_args))
7999 {
8000 com_err(whoami, 0, "Unable to resolve machine name %s : %s",
8001 MachineName, error_message(rc));
8002 strcpy(MachineName, "");
8003 return(0);
8004 }
8005
8006 if (strlen(NewMachineName) != 0)
8007 strcpy(MachineName, NewMachineName);
8008 else
8009 strcpy(MachineName, "");
8010
8011 return(0);
8012}
8013
8014int ProcessMachineName(int ac, char **av, void *ptr)
8015{
8016 char **call_args;
8017 char MachineName[1024];
8018 char *szDot;
8019 int i;
8020
8021 call_args = ptr;
8022
8023 if (strlen(call_args[0]) == 0)
8024 {
8025 strcpy(MachineName, av[0]);
8026
8027 for (i = 0; i < (int)strlen(MachineName); i++)
8028 MachineName[i] = toupper(MachineName[i]);
8029
8030 szDot = strchr(MachineName,'.');
8031
8032 if ((szDot) && (!strcasecmp(szDot+1,DOMAIN_SUFFIX)))
8033 {
8034 strcpy(call_args[0], MachineName);
8035 }
8036 }
8037
8038 return(0);
8039}
8040
8041void SwitchSFU(LDAPMod **mods, int *UseSFU30, int n)
8042{
8043 int i;
8044
8045 if (*UseSFU30)
8046 {
8047 for (i = 0; i < n; i++)
8048 {
8049 if (!strcmp(mods[i]->mod_type, "msSFU30UidNumber"))
8050 mods[i]->mod_type = "uidNumber";
8051 }
8052
8053 (*UseSFU30) = 0;
8054 }
8055 else
8056 {
8057 for (i = 0; i < n; i++)
8058 {
8059 if (!strcmp(mods[i]->mod_type, "uidNumber"))
8060 mods[i]->mod_type = "msSFU30UidNumber";
8061 }
8062
8063 (*UseSFU30) = 1;
8064 }
8065}
8066
8067int SetHomeDirectory(LDAP *ldap_handle, char *user_name,
8068 char *DistinguishedName,
8069 char *WinHomeDir, char *WinProfileDir,
8070 char **homedir_v, char **winProfile_v,
8071 char **drives_v, LDAPMod **mods,
8072 int OpType, int n)
8073{
61a2844b 8074 char cWeight[3];
8075 char cPath[1024];
8076 char path[1024];
8077 char winPath[1024];
8078 char winProfile[1024];
8079 char homeDrive[8];
8080 char homedir[1024];
8081 char apple_homedir[1024];
8082 char *apple_homedir_v[] = {NULL, NULL};
8083 int last_weight;
8084 int i;
8085 int rc;
8086 LDAPMod *DelMods[20];
5f6343e6 8087 char *argv[3];
8088 char *save_argv[FS_END];
8089 char *fsgroup_save_argv[2];
8090
61a2844b 8091 memset(homeDrive, '\0', sizeof(homeDrive));
8092 memset(path, '\0', sizeof(path));
8093 memset(winPath, '\0', sizeof(winPath));
8094 memset(winProfile, '\0', sizeof(winProfile));
61a2844b 8095
8096 if(!ActiveDirectory)
8097 {
5f6343e6 8098 if (rc = moira_connect())
8099 {
c9ef9269 8100 critical_alert("Ldap incremental",
5f6343e6 8101 "Error contacting Moira server : %s",
8102 error_message(rc));
8103 return;
8104 }
8105
8106 argv[0] = user_name;
8107
8108 if (!(rc = mr_query("get_filesys_by_label", 1, argv, save_query_info,
8109 save_argv)))
8110 {
8111 if(!strcmp(save_argv[FS_TYPE], "FSGROUP") ||
8112 !strcmp(save_argv[FS_TYPE], "MUL"))
61a2844b 8113 {
5f6343e6 8114
8115 argv[0] = save_argv[FS_NAME];
8116 fsgCount = 0;
8117
8118 if (!(rc = mr_query("get_fsgroup_members", 1, argv,
8119 save_fsgroup_info, fsgroup_save_argv)))
61a2844b 8120 {
5f6343e6 8121 if(fsgCount)
8122 {
8123 argv[0] = fsgroup_save_argv[0];
8124
8125 if (!(rc = mr_query("get_filesys_by_label", 1, argv,
8126 save_query_info, save_argv)))
8127 {
8128 strcpy(path, save_argv[FS_PACK]);
8129 }
8130 }
61a2844b 8131 }
8132 }
5f6343e6 8133 else
8134 {
8135 strcpy(path, save_argv[FS_PACK]);
8136 }
61a2844b 8137 }
5f6343e6 8138
8139 moira_disconnect();
8140
8141 if (strlen(path))
61a2844b 8142 {
5f6343e6 8143 if (!strnicmp(path, AFS, strlen(AFS)))
61a2844b 8144 {
5f6343e6 8145 sprintf(homedir, "%s", path);
8146 sprintf(apple_homedir, "%s/MacData", path);
8147 homedir_v[0] = homedir;
8148 apple_homedir_v[0] = apple_homedir;
61a2844b 8149 ADD_ATTR("homeDirectory", homedir_v, OpType);
8150 ADD_ATTR("apple-user-homeDirectory", apple_homedir_v,
8151 OpType);
8152 }
8153 }
5f6343e6 8154 else
8155 {
8156 homedir_v[0] = "NONE";
8157 apple_homedir_v[0] = "NONE";
8158 ADD_ATTR("homeDirectory", homedir_v, OpType);
8159 ADD_ATTR("apple-user-homeDirectory", apple_homedir_v,
8160 OpType);
8161 }
8162
61a2844b 8163 return(n);
8164 }
5f6343e6 8165
61a2844b 8166 if ((!strcasecmp(WinHomeDir, "[afs]")) ||
8167 (!strcasecmp(WinProfileDir, "[afs]")))
8168 {
5f6343e6 8169 if (rc = moira_connect())
8170 {
c9ef9269 8171 critical_alert("Ldap incremental",
5f6343e6 8172 "Error contacting Moira server : %s",
8173 error_message(rc));
8174 return;
8175 }
8176
8177 argv[0] = user_name;
61a2844b 8178
5f6343e6 8179 if (!(rc = mr_query("get_filesys_by_label", 1, argv, save_query_info,
8180 save_argv)))
8181 {
8182 if(!strcmp(save_argv[FS_TYPE], "FSGROUP") ||
8183 !strcmp(save_argv[FS_TYPE], "MUL"))
8184 {
8185
8186 argv[0] = save_argv[FS_NAME];
8187 fsgCount = 0;
8188
8189 if (!(rc = mr_query("get_fsgroup_members", 1, argv,
8190 save_fsgroup_info, fsgroup_save_argv)))
8191 {
8192 if(fsgCount)
8193 {
8194 argv[0] = fsgroup_save_argv[0];
8195
8196 if (!(rc = mr_query("get_filesys_by_label", 1, argv,
8197 save_query_info, save_argv)))
8198 {
8199 strcpy(path, save_argv[FS_PACK]);
8200 }
8201 }
8202 }
8203 }
8204 else
8205 {
8206 strcpy(path, save_argv[FS_PACK]);
8207 }
8208 }
8209
8210 moira_disconnect();
61a2844b 8211
5f6343e6 8212 if (strlen(path))
8213 {
8214 if (!strnicmp(path, AFS, strlen(AFS)))
8215 {
8216 AfsToWinAfs(path, winPath);
8217 strcpy(winProfile, winPath);
8218 strcat(winProfile, "\\.winprofile");
8219 }
8220 }
61a2844b 8221 else
8222 return(n);
8223 }
8224
8225 if ((!strcasecmp(WinHomeDir, "[dfs]")) ||
8226 (!strcasecmp(WinProfileDir, "[dfs]")))
8227 {
8228 sprintf(path, "\\\\%s\\dfs\\profiles\\%c\\%s", ldap_domain,
8229 user_name[0], user_name);
8230
8231 if (!strcasecmp(WinProfileDir, "[dfs]"))
8232 {
8233 strcpy(winProfile, path);
8234 strcat(winProfile, "\\.winprofile");
8235 }
8236
8237 if (!strcasecmp(WinHomeDir, "[dfs]"))
8238 strcpy(winPath, path);
8239 }
8240
61a2844b 8241 if (!strcasecmp(WinHomeDir, "[local]"))
8242 memset(winPath, '\0', sizeof(winPath));
8243 else if (!strcasecmp(WinHomeDir, "[afs]") ||
8244 !strcasecmp(WinHomeDir, "[dfs]"))
8245 {
8246 strcpy(homeDrive, "H:");
8247 }
8248 else
8249 {
8250 strcpy(winPath, WinHomeDir);
8251 if (!strncmp(WinHomeDir, "\\\\", 2))
8252 {
8253 strcpy(homeDrive, "H:");
8254 }
8255 }
8256
8257 // nothing needs to be done if WinProfileDir is [afs].
8258 if (!strcasecmp(WinProfileDir, "[local]"))
8259 memset(winProfile, '\0', sizeof(winProfile));
8260 else if (strcasecmp(WinProfileDir, "[afs]") &&
8261 strcasecmp(WinProfileDir, "[dfs]"))
8262 {
8263 strcpy(winProfile, WinProfileDir);
8264 }
8265
8266 if (strlen(winProfile) != 0)
8267 {
8268 if (winProfile[strlen(winProfile) - 1] == '\\')
8269 winProfile[strlen(winProfile) - 1] = '\0';
8270 }
8271
8272 if (strlen(winPath) != 0)
8273 {
8274 if (winPath[strlen(winPath) - 1] == '\\')
8275 winPath[strlen(winPath) - 1] = '\0';
8276 }
8277
8278 if ((winProfile[1] == ':') && (strlen(winProfile) == 2))
8279 strcat(winProfile, "\\");
8280
8281 if ((winPath[1] == ':') && (strlen(winPath) == 2))
8282 strcat(winPath, "\\");
8283
8284 if (strlen(winPath) == 0)
8285 {
8286 if (OpType == LDAP_MOD_REPLACE)
8287 {
8288 i = 0;
8289 DEL_ATTR("homeDirectory", LDAP_MOD_DELETE);
8290 DelMods[i] = NULL;
8291 //unset homeDirectory attribute for user.
8292 rc = ldap_modify_s(ldap_handle, DistinguishedName, DelMods);
8293 free(DelMods[0]);
8294 }
8295 }
8296 else
8297 {
8298 homedir_v[0] = strdup(winPath);
8299 ADD_ATTR("homeDirectory", homedir_v, OpType);
8300 }
8301
8302 if (strlen(winProfile) == 0)
8303 {
8304 if (OpType == LDAP_MOD_REPLACE)
8305 {
8306 i = 0;
8307 DEL_ATTR("profilePath", LDAP_MOD_DELETE);
8308 DelMods[i] = NULL;
8309 //unset profilePate attribute for user.
8310 rc = ldap_modify_s(ldap_handle, DistinguishedName, DelMods);
8311 free(DelMods[0]);
8312 }
8313 }
8314 else
8315 {
8316 winProfile_v[0] = strdup(winProfile);
8317 ADD_ATTR("profilePath", winProfile_v, OpType);
8318 }
8319
8320 if (strlen(homeDrive) == 0)
8321 {
8322 if (OpType == LDAP_MOD_REPLACE)
8323 {
8324 i = 0;
8325 DEL_ATTR("homeDrive", LDAP_MOD_DELETE);
8326 DelMods[i] = NULL;
8327 //unset homeDrive attribute for user
8328 rc = ldap_modify_s(ldap_handle, DistinguishedName, DelMods);
8329 free(DelMods[0]);
8330 }
8331 }
8332 else
8333 {
8334 drives_v[0] = strdup(homeDrive);
8335 ADD_ATTR("homeDrive", drives_v, OpType);
8336 }
8337
8338 return(n);
8339}
8340
8341int attribute_update(LDAP *ldap_handle, char *distinguished_name,
8342 char *attribute_value, char *attribute, char *user_name)
8343{
8344 char *mod_v[] = {NULL, NULL};
8345 LDAPMod *DelMods[20];
8346 LDAPMod *mods[20];
8347 int n;
8348 int i;
8349 int rc;
8350
8351 if (strlen(attribute_value) == 0)
8352 {
8353 i = 0;
8354 DEL_ATTR(attribute, LDAP_MOD_DELETE);
8355 DelMods[i] = NULL;
8356 rc = ldap_modify_s(ldap_handle, distinguished_name, DelMods);
8357 free(DelMods[0]);
8358 }
8359 else
8360 {
8361 n = 0;
8362 mod_v[0] = attribute_value;
8363 ADD_ATTR(attribute, mod_v, LDAP_MOD_REPLACE);
8364 mods[n] = NULL;
8365
8366 if ((rc = ldap_modify_s(ldap_handle, distinguished_name,
8367 mods)) != LDAP_SUCCESS)
8368 {
8369 free(mods[0]);
8370 n = 0;
8371 mod_v[0] = attribute_value;
8372 ADD_ATTR(attribute, mod_v, LDAP_MOD_ADD);
8373 mods[n] = NULL;
8374
8375 if ((rc = ldap_modify_s(ldap_handle, distinguished_name,
8376 mods)) != LDAP_SUCCESS)
8377 {
8378 com_err(whoami, 0, "Unable to change the %s attribute for %s "
c9ef9269 8379 "in the directory : %s",
61a2844b 8380 attribute, user_name, ldap_err2string(rc));
8381 }
8382 }
8383
8384 free(mods[0]);
8385 }
8386
8387 return(rc);
8388}
8389
8390void StringTrim(char *StringToTrim)
8391{
8392 char *t, *s;
8393 char *save;
8394
8395 save = strdup(StringToTrim);
8396
8397 s = save;
8398
8399 while (isspace(*s))
8400 s++;
8401
8402 /* skip to end of string */
8403 if (*s == '\0')
8404 {
8405 if (*save)
8406 *save = '\0';
8407 strcpy(StringToTrim, save);
8408 return;
8409 }
8410
8411 for (t = s; *t; t++)
8412 continue;
8413
8414 while (t > s)
8415 {
8416 --t;
8417 if (!isspace(*t))
8418 {
8419 t++;
8420 break;
8421 }
8422 }
8423
8424 if (*t)
8425 *t = '\0';
8426
8427 strcpy(StringToTrim, s);
8428 return;
8429}
8430
8431int ReadConfigFile(char *DomainName)
8432{
8433 int Count;
8434 int i;
8435 int k;
8436 char temp[256];
8437 char temp1[256];
8438 FILE *fptr;
8439
8440 Count = 0;
8441
8442 sprintf(temp, "%s%s.cfg", CFG_PATH, DomainName);
8443
8444 if ((fptr = fopen(temp, "r")) != NULL)
8445 {
8446 while (fgets(temp, sizeof(temp), fptr) != 0)
8447 {
8448 for (i = 0; i < (int)strlen(temp); i++)
8449 temp[i] = toupper(temp[i]);
8450
8451 if (temp[strlen(temp) - 1] == '\n')
8452 temp[strlen(temp) - 1] = '\0';
8453
8454 StringTrim(temp);
8455
8456 if (strlen(temp) == 0)
8457 continue;
8458
8459 if (!strncmp(temp, DOMAIN, strlen(DOMAIN)))
8460 {
8461 if (strlen(temp) > (strlen(DOMAIN)))
8462 {
8463 strcpy(ldap_domain, &temp[strlen(DOMAIN)]);
8464 StringTrim(ldap_domain);
8465 }
8466 }
8467 else if (!strncmp(temp, REALM, strlen(REALM)))
8468 {
8469 if (strlen(temp) > (strlen(REALM)))
8470 {
8471 strcpy(ldap_realm, &temp[strlen(REALM)]);
8472 StringTrim(ldap_realm);
8473 }
8474 }
8475 else if (!strncmp(temp, PORT, strlen(PORT)))
8476 {
8477 if (strlen(temp) > (strlen(PORT)))
8478 {
8479 strcpy(ldap_port, &temp[strlen(PORT)]);
8480 StringTrim(ldap_port);
8481 }
8482 }
8483 else if (!strncmp(temp, PRINCIPALNAME, strlen(PRINCIPALNAME)))
8484 {
8485 if (strlen(temp) > (strlen(PRINCIPALNAME)))
8486 {
8487 strcpy(PrincipalName, &temp[strlen(PRINCIPALNAME)]);
8488 StringTrim(PrincipalName);
8489 }
8490 }
8491 else if (!strncmp(temp, SERVER, strlen(SERVER)))
8492 {
8493 if (strlen(temp) > (strlen(SERVER)))
8494 {
8495 ServerList[Count] = calloc(1, 256);
8496 strcpy(ServerList[Count], &temp[strlen(SERVER)]);
8497 StringTrim(ServerList[Count]);
8498 ++Count;
8499 }
8500 }
8501 else if (!strncmp(temp, MSSFU, strlen(MSSFU)))
8502 {
8503 if (strlen(temp) > (strlen(MSSFU)))
8504 {
8505 strcpy(temp1, &temp[strlen(MSSFU)]);
8506 StringTrim(temp1);
8507 if (!strcmp(temp1, SFUTYPE))
8508 UseSFU30 = 1;
8509 }
8510 }
8511 else if (!strncmp(temp, GROUP_SUFFIX, strlen(GROUP_SUFFIX)))
8512 {
8513 if (strlen(temp) > (strlen(GROUP_SUFFIX)))
8514 {
8515 strcpy(temp1, &temp[strlen(GROUP_SUFFIX)]);
8516 StringTrim(temp1);
8517 if (!strcasecmp(temp1, "NO"))
8518 {
8519 UseGroupSuffix = 0;
8520 memset(group_suffix, '\0', sizeof(group_suffix));
8521 }
8522 }
8523 }
8524 else if (!strncmp(temp, GROUP_TYPE, strlen(GROUP_TYPE)))
8525 {
8526 if (strlen(temp) > (strlen(GROUP_TYPE)))
8527 {
8528 strcpy(temp1, &temp[strlen(GROUP_TYPE)]);
8529 StringTrim(temp1);
8530 if (!strcasecmp(temp1, "UNIVERSAL"))
8531 UseGroupUniversal = 1;
8532 }
8533 }
8534 else if (!strncmp(temp, SET_GROUP_ACE, strlen(SET_GROUP_ACE)))
8535 {
8536 if (strlen(temp) > (strlen(SET_GROUP_ACE)))
8537 {
8538 strcpy(temp1, &temp[strlen(SET_GROUP_ACE)]);
8539 StringTrim(temp1);
8540 if (!strcasecmp(temp1, "NO"))
8541 SetGroupAce = 0;
8542 }
8543 }
8544 else if (!strncmp(temp, SET_PASSWORD, strlen(SET_PASSWORD)))
8545 {
8546 if (strlen(temp) > (strlen(SET_PASSWORD)))
8547 {
8548 strcpy(temp1, &temp[strlen(SET_PASSWORD)]);
8549 StringTrim(temp1);
8550 if (!strcasecmp(temp1, "NO"))
8551 SetPassword = 0;
8552 }
8553 }
8554 else if (!strncmp(temp, EXCHANGE, strlen(EXCHANGE)))
8555 {
8556 if (strlen(temp) > (strlen(EXCHANGE)))
8557 {
8558 strcpy(temp1, &temp[strlen(EXCHANGE)]);
8559 StringTrim(temp1);
8560 if (!strcasecmp(temp1, "YES"))
8561 Exchange = 1;
8562 }
8563 }
8564 else if (!strncmp(temp, PROCESS_MACHINE_CONTAINER,
8565 strlen(PROCESS_MACHINE_CONTAINER)))
8566 {
8567 if (strlen(temp) > (strlen(PROCESS_MACHINE_CONTAINER)))
8568 {
8569 strcpy(temp1, &temp[strlen(PROCESS_MACHINE_CONTAINER)]);
8570 StringTrim(temp1);
8571 if (!strcasecmp(temp1, "NO"))
8572 ProcessMachineContainer = 0;
8573 }
8574 }
8575 else if (!strncmp(temp, ACTIVE_DIRECTORY,
8576 strlen(ACTIVE_DIRECTORY)))
8577 {
8578 if (strlen(temp) > (strlen(ACTIVE_DIRECTORY)))
8579 {
8580 strcpy(temp1, &temp[strlen(ACTIVE_DIRECTORY)]);
8581 StringTrim(temp1);
8582 if (!strcasecmp(temp1, "NO"))
8583 ActiveDirectory = 0;
8584 }
8585 }
e8332ac3 8586 else if (!strncmp(temp, GROUP_POPULATE_MEMBERS,
8587 strlen(GROUP_POPULATE_MEMBERS)))
8588 {
8589 if (strlen(temp) > (strlen(GROUP_POPULATE_MEMBERS)))
8590 {
8591 strcpy(temp1, &temp[strlen(GROUP_POPULATE_MEMBERS)]);
8592 StringTrim(temp1);
8593 if (!strcasecmp(temp1, "DELETE"))
8594 {
8595 GroupPopulateDelete = 1;
8596 }
8597 }
8598 }
61a2844b 8599 else
8600 {
8601 if (strlen(ldap_domain) != 0)
8602 {
8603 memset(ldap_domain, '\0', sizeof(ldap_domain));
8604 break;
8605 }
8606
8607 if (strlen(temp) != 0)
8608 strcpy(ldap_domain, temp);
8609 }
8610 }
8611 fclose(fptr);
8612 }
8613
8614 if (strlen(ldap_domain) == 0)
8615 {
8616 strcpy(ldap_domain, DomainName);
8617 }
8618
8619 if (Count == 0)
8620 return(0);
8621
8622 for (i = 0; i < Count; i++)
8623 {
8624 if (ServerList[i] != 0)
8625 {
8626 for (k = 0; k < (int)strlen(ServerList[i]); k++)
8627 ServerList[i][k] = toupper(ServerList[i][k]);
8628 }
8629 }
8630
8631 return(0);
8632}
8633
8634int ReadDomainList()
8635{
8636 int Count;
8637 int i;
8638 char temp[128];
8639 char temp1[128];
8640 FILE *fptr;
8641 unsigned char c[11];
8642 unsigned char stuff[256];
8643 int rc;
8644 int ok;
8645
8646 Count = 0;
8647 sprintf(temp, "%s%s", CFG_PATH, WINADCFG);
8648
8649 if ((fptr = fopen(temp, "r")) != NULL)
8650 {
8651 while (fgets(temp, sizeof(temp), fptr) != 0)
8652 {
8653 for (i = 0; i < (int)strlen(temp); i++)
8654 temp[i] = toupper(temp[i]);
8655
8656 if (temp[strlen(temp) - 1] == '\n')
8657 temp[strlen(temp) - 1] = '\0';
8658
8659 StringTrim(temp);
8660
8661 if (strlen(temp) == 0)
8662 continue;
8663
8664 if (!strncmp(temp, DOMAIN, strlen(DOMAIN)))
8665 {
8666 if (strlen(temp) > (strlen(DOMAIN)))
8667 {
8668 strcpy(temp1, &temp[strlen(DOMAIN)]);
8669 StringTrim(temp1);
8670 strcpy(temp, temp1);
8671 }
8672 }
8673
8674 strcpy(DomainNames[Count], temp);
8675 StringTrim(DomainNames[Count]);
8676 ++Count;
8677 }
8678
8679 fclose(fptr);
8680 }
8681
8682 if (Count == 0)
8683 {
8684 critical_alert("incremental", "%s", "ldap.incr cannot run due to a "
8685 "configuration error in ldap.cfg");
8686 return(1);
8687 }
8688
8689 return(0);
8690}
8691
8692int email_isvalid(const char *address) {
8693 int count = 0;
8694 const char *c, *domain;
8695 static char *rfc822_specials = "()<>@,;:\\\"[]";
8696
8697 if(address[strlen(address) - 1] == '.')
8698 return 0;
8699
8700 /* first we validate the name portion (name@domain) */
8701 for (c = address; *c; c++) {
8702 if (*c == '\"' && (c == address || *(c - 1) == '.' || *(c - 1) ==
8703 '\"')) {
8704 while (*++c) {
8705 if (*c == '\"')
8706 break;
8707 if (*c == '\\' && (*++c == ' '))
8708 continue;
8709 if (*c <= ' ' || *c >= 127)
8710 return 0;
8711 }
8712
8713 if (!*c++)
8714 return 0;
8715 if (*c == '@')
8716 break;
8717 if (*c != '.')
8718 return 0;
8719 continue;
8720 }
8721
8722 if (*c == '@')
8723 break;
8724 if (*c <= ' ' || *c >= 127)
8725 return 0;
8726 if (strchr(rfc822_specials, *c))
8727 return 0;
8728 }
8729
8730 if (c == address || *(c - 1) == '.')
8731 return 0;
8732
8733 /* next we validate the domain portion (name@domain) */
8734 if (!*(domain = ++c)) return 0;
8735 do {
8736 if (*c == '.') {
8737 if (c == domain || *(c - 1) == '.')
8738 return 0;
8739 count++;
8740 }
8741 if (*c <= ' ' || *c >= 127)
8742 return 0;
8743 if (strchr(rfc822_specials, *c))
8744 return 0;
8745 } while (*++c);
8746
8747 return (count >= 1);
8748}
8749
8750int find_homeMDB(LDAP *ldap_handle, char *dn_path, char **homeMDB,
8751 char **homeServerName)
8752{
8753 LK_ENTRY *group_base;
8754 LK_ENTRY *sub_group_base;
8755 LK_ENTRY *gPtr;
8756 LK_ENTRY *sub_gPtr;
8757 int group_count;
8758 int sub_group_count;
8759 char filter[1024];
8760 char sub_filter[1024];
8761 char search_path[1024];
8762 char range[1024];
8763 char *attr_array[3];
8764 char *s;
8765 int homeMDB_count = -1;
8766 int rc;
8767 int i;
8768 int mdbbl_count;
8769 int rangeStep = 1500;
8770 int rangeLow = 0;
8771 int rangeHigh = rangeLow + (rangeStep - 1);
8772 int isLast = 0;
8773
8774 /* Grumble..... microsoft not making it searchable from the root *grr* */
8775
8776 memset(filter, '\0', sizeof(filter));
8777 memset(search_path, '\0', sizeof(search_path));
8778
8779 sprintf(filter, "(objectClass=msExchMDB)");
8780 sprintf(search_path, "CN=Configuration,%s", dn_path);
8781 attr_array[0] = "distinguishedName";
8782 attr_array[1] = NULL;
8783
8784 group_base = NULL;
8785 group_count = 0;
8786
8787 if ((rc = linklist_build(ldap_handle, search_path, filter, attr_array,
8788 &group_base, &group_count,
8789 LDAP_SCOPE_SUBTREE)) != 0)
8790 {
8791 com_err(whoami, 0, "Unable to find msExchMDB %s",
8792 ldap_err2string(rc));
8793 return(rc);
8794 }
8795
8796 if (group_count)
8797 {
8798 gPtr = group_base;
8799
8800 while(gPtr) {
8801 if (((s = strstr(gPtr->dn, "Public")) != (char *) NULL) ||
8802 ((s = strstr(gPtr->dn, "Recover")) != (char *) NULL) ||
8803 ((s = strstr(gPtr->dn, "Reserve")) != (char *) NULL))
8804 {
8805 gPtr = gPtr->next;
8806 continue;
8807 }
8808
8809 /*
8810 * Due to limits in active directory we need to use the LDAP
8811 * range semantics to query and return all the values in
8812 * large lists, we will stop increasing the range when
8813 * the result count is 0.
8814 */
8815
8816 i = 0;
8817 mdbbl_count = 0;
8818
8819 for(;;)
8820 {
8821 memset(sub_filter, '\0', sizeof(sub_filter));
8822 memset(range, '\0', sizeof(range));
8823 sprintf(sub_filter, "(objectClass=msExchMDB)");
8824
8825 if(isLast)
8826 sprintf(range, "homeMDBBL;Range=%d-*", rangeLow);
8827 else
8828 sprintf(range, "homeMDBBL;Range=%d-%d", rangeLow, rangeHigh);
8829
8830 attr_array[0] = range;
8831 attr_array[1] = NULL;
8832
8833 sub_group_base = NULL;
8834 sub_group_count = 0;
8835
8836 if ((rc = linklist_build(ldap_handle, gPtr->dn, sub_filter,
8837 attr_array, &sub_group_base,
8838 &sub_group_count,
8839 LDAP_SCOPE_SUBTREE)) != 0)
8840 {
8841 com_err(whoami, 0, "Unable to find homeMDBBL %s",
8842 ldap_err2string(rc));
8843 return(rc);
8844 }
8845
8846 if(!sub_group_count)
8847 {
8848 if(isLast)
8849 {
8850 isLast = 0;
8851 rangeLow = 0;
8852 rangeHigh = rangeLow + (rangeStep - 1);
8853 break;
8854 }
8855 else
8856 isLast++;
8857 }
8858
8859 mdbbl_count += sub_group_count;
8860 rangeLow = rangeHigh + 1;
8861 rangeHigh = rangeLow + (rangeStep - 1);
8862 }
8863
8864 /* First time through, need to initialize or update the least used */
8865
8866 com_err(whoami, 0, "Mail store %s, count %d", gPtr->dn,
8867 mdbbl_count);
8868
8869 if(mdbbl_count < homeMDB_count || homeMDB_count == -1)
8870 {
8871 homeMDB_count = mdbbl_count;
8872 *homeMDB = strdup(gPtr->dn);
8873 }
8874
8875 gPtr = gPtr->next;
8876 linklist_free(sub_group_base);
8877 }
8878 }
8879
8880 linklist_free(group_base);
8881
8882 /*
8883 * Ok found the server least allocated need to now query to get its
8884 * msExchHomeServerName so we can set it as a user attribute
8885 */
8886
8887 attr_array[0] = "legacyExchangeDN";
8888 attr_array[1] = NULL;
8889
8890 group_count = 0;
8891 group_base = NULL;
8892
8893 if ((rc = linklist_build(ldap_handle, *homeMDB, filter,
8894 attr_array, &group_base,
8895 &group_count,
8896 LDAP_SCOPE_SUBTREE)) != 0)
8897 {
8898 com_err(whoami, 0, "Unable to find msExchHomeServerName %s",
8899 ldap_err2string(rc));
8900 return(rc);
8901 }
8902
8903 if(group_count)
8904 {
8905 *homeServerName = strdup(group_base->value);
8906 if((s = strrchr(*homeServerName, '/')) != (char *) NULL)
8907 {
8908 *s = '\0';
8909 }
8910 }
8911
8912 linklist_free(group_base);
8913
8914 return(rc);
8915}
8916
8917char *lowercase(char *s)
8918{
8919 char *p;
8920
8921 for (p = s; *p; p++)
8922 {
8923 if (isupper(*p))
8924 *p = tolower(*p);
8925 }
8926 return s;
8927}
8928
8929char *uppercase(char *s)
8930{
8931 char *p;
8932
8933 for (p = s; *p; p++)
8934 {
8935 if (islower(*p))
8936 *p = toupper(*p);
8937 }
8938 return s;
8939}
8940
8941char *escape_string(char *s)
8942{
8943 char *p, *q;
8944 char string[1024];
8945 char temp[1024];
8946 int i = 0;
8947 int spaces = 0;
8948
8949 memset(string, '\0', sizeof(string));
8950
8951 q = s;
8952
61a2844b 8953 /* Escape any special characters */
8954
8955 for(; *q != '\0'; q++) {
8956 if(*q == ',')
8957 string[i++] = '\\';
8958 if(*q == '+')
8959 string[i++] = '\\';
8960 if(*q == '"')
8961 string[i++] = '\\';
8962 if(*q == '\\')
8963 string[i++] = '\\';
8964 if(*q == '<')
8965 string[i++] = '\\';
8966 if(*q == '>')
8967 string[i++] = '\\';
8968 if(*q == ';')
8969 string[i++] = '\\';
8970 if(*q == '#')
8971 string[i++] = '\\';
8972 if(*q == '=')
8973 string[i++] = '\\';
8974
8975 string[i++] = *q;
8976 }
8977
8978 return strdup(string);
8979}
8980
8981int save_query_info(int argc, char **argv, void *hint)
8982{
8983 int i;
8984 char **nargv = hint;
8985
8986 for(i = 0; i < argc; i++)
8987 nargv[i] = strdup(argv[i]);
8988
8989 return MR_CONT;
8990}
5f6343e6 8991
8992int save_fsgroup_info(int argc, char **argv, void *hint)
8993{
8994 int i;
8995 char **nargv = hint;
8996
8997 if(!fsgCount)
8998 {
8999 for(i = 0; i < argc; i++)
9000 nargv[i] = strdup(argv[i]);
9001
9002 fsgCount++;
9003 }
9004
9005 return MR_CONT;
9006}
This page took 1.236419 seconds and 5 git commands to generate.