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