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