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