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