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