]> andersk Git - moira.git/blame - incremental/winad/winad.c
Make "user foo" in moira.conf actually work.
[moira.git] / incremental / winad / winad.c
CommitLineData
5d0a7127 1/* $Header$
89db421e 2/* winad.incr arguments examples
cd9e6b16 3 *
89db421e 4 * arguments when moira creates the account - ignored by winad.incr since the account is unusable.
5 * users 0 11 #45198 45198 /bin/cmd cmd Last First Middle 0 950000001 2000 121049
6 * login, unix_uid, shell, winconsoleshell, last, first, middle, status, mitid, type, moiraid
cd9e6b16 7 *
89db421e 8 * arguments for creating or updating a user account
3abb4456 9 * users 11 11 username 45206 /bin/cmd cmd Last First Middle 2 950000001 STAFF 121058 PathToHomeDir PathToProfileDir username 45206 /bin/cmd cmd Last First Middle 1 950000001 STAFF 121058 PathToHomeDir PathToProfileDir
10 * users 11 11 #45206 45206 /bin/cmd cmd Last First Middle 0 950000001 STAFF 121058 PathToHomeDir PathToProfileDir newuser 45206 /bin/cmd cmd Last First Middle 2 950000001 STAFF 121058 PathToHomeDir PathToProfileDir
89db421e 11 * login, unix_uid, shell, winconsoleshell, last, first, middle, status, mitid, type, moiraid
78af4e6e 12 *
89db421e 13 * arguments for deactivating/deleting a user account
3abb4456 14 * users 11 11 username 45206 /bin/cmd cmd Last First Middle 1 950000001 STAFF 121058 PathToHomeDir PathToProfileDir username 45206 /bin/cmd cmd Last First Middle 3 950000001 STAFF 121058 PathToHomeDir PathToProfileDir
15 * users 11 11 username 45206 /bin/cmd cmd Last First Middle 2 950000001 STAFF 121058 PathToHomeDir PathToProfileDir username 45206 /bin/cmd cmd Last First Middle 3 950000001 STAFF 121058 PathToHomeDir PathToProfileDir
89db421e 16 * login, unix_uid, shell, winconsoleshell, last, first, middle, status, mitid, type, moiraid
cd9e6b16 17 *
89db421e 18 * arguments for reactivating a user account
19 * users 11 11 username 45206 /bin/cmd cmd Last First Middle 3 950000001 STAFF 121058 username 45206 /bin/cmd cmd Last First Middle 1 950000001 STAFF 121058
20 * users 11 11 username 45206 /bin/cmd cmd Last First Middle 3 950000001 STAFF 121058 username 45206 /bin/cmd cmd Last First Middle 2 950000001 STAFF 121058
21 * login, unix_uid, shell, winconsoleshell, last, first, middle, status, mitid, type, moiraid
cd9e6b16 22 *
89db421e 23 * arguments for changing user name
3abb4456 24 * users 11 11 oldusername 45206 /bin/cmd cmd Last First Middle 1 950000001 STAFF 121058 PathToHomeDir PathToProfileDir newusername 45206 /bin/cmd cmd Last First Middle 1 950000001 STAFF 121058 PathToHomeDir PathToProfileDir
89db421e 25 * login, unix_uid, shell, winconsoleshell, last, first, middle, status, mitid, type, moiraid
cd9e6b16 26 *
89db421e 27 * arguments for expunging a user
28 * users 11 0 username 45198 /bin/cmd cmd Last First Middle 0 950000001 2000 121049
29 * login, unix_uid, shell, winconsoleshell, last, first, middle, status, mitid, type, moiraid
30 *
31 * arguments for creating a "special" group/list
32 * list 0 11 listname 1 1 0 0 0 -1 NONE 0 description 92616
33 * listname, active, publicflg, hidden, maillist, grouplist, gid, acl_type, acl_id, description, moiraid
9db0b148 34 *
89db421e 35 * arguments for creating a "mail" group/list
36 * list 0 11 listname 1 1 0 1 0 -1 NONE 0 description 92616
37 * listname, active, publicflg, hidden, maillist, grouplist, gid, acl_type, acl_id, description, moiraid
38 *
39 * arguments for creating a "group" group/list
40 * list 0 11 listname 1 1 0 0 1 -1 NONE 0 description 92616
41 * listname, active, publicflg, hidden, maillist, grouplist, gid, acl_type, acl_id, description, moiraid
42 *
43 * arguments for creating a "group/mail" group/list
44 * list 0 11 listname 1 1 0 1 1 -1 NONE 0 description 92616
45 * listname, active, publicflg, hidden, maillist, grouplist, gid, acl_type, acl_id, description, moiraid
46 *
47 * arguments to add a USER member to group/list
48 * imembers 0 12 listname USER userName 1 1 0 0 0 -1 1 92616 121047
49 * list_name, user_type, name, active, publicflg, hidden, maillist, grouplist, gid, userStatus, moiraListId, moiraUserId
50 *
51 * arguments to add a STRING or KERBEROS member to group/list
52 * imembers 0 10 listname STRING stringName 1 1 0 0 0 -1 92616
53 * imembers 0 10 listlistnameName KERBEROS kerberosName 1 1 0 0 0 -1 92616
54 * list_name, user_type, name, active, publicflg, hidden, maillist, grouplist, gid, moiraListId
55 *
56 * NOTE: group members of type LIST are ignored.
57 *
58 * arguments to remove a USER member to group/list
59 * imembers 12 0 listname USER userName 1 1 0 0 0 -1 1 92616 121047
60 * list_name, user_type, name, active, publicflg, hidden, maillist, grouplist, gid, userStatus, moiraListId, moiraUserId
61 *
62 * arguments to remove a STRING or KERBEROS member to group/list
63 * imembers 10 0 listname STRING stringName 1 1 0 0 0 -1 92616
64 * imembers 10 0 listname KERBEROS kerberosName 1 1 0 0 0 -1 92616
65 * list_name, user_type, name, active, publicflg, hidden, maillist, grouplist, gid, moiraListId
9db0b148 66 *
89db421e 67 * NOTE: group members of type LIST are ignored.
f75f605a 68 *
89db421e 69 * arguments for renaming a group/list
70 * list 11 11 oldlistname 1 1 0 0 0 -1 NONE 0 description 92616 newlistname 1 1 0 0 0 -1 description 0 92616
71 * name, active, publicflg, hidden, maillist, grouplist, gid, acl_type, acl_id, description, moiraListId
f75f605a 72 *
89db421e 73 * arguments for deleting a group/list
74 * list 11 0 listname 1 1 0 0 0 -1 NONE 0 description 92616
75 * name, active, publicflg, hidden, maillist, grouplist, gid, acl_type, acl_id, description, moiraListId
6c8f12af 76 *
89db421e 77 * arguments for adding a file system
78 * filesys 0 12 username AFS ATHENA.MIT.EDU /afs/athena.mit.edu/user/n/e/username /mit/username w descripton username wheel 1 HOMEDIR 101727
79 *
80 * arguments for deleting a file system
81 * filesys 12 0 username AFS ATHENA.MIT.EDU /afs/athena.mit.edu/user/n/e/username /mit/username w descripton username wheel 1 HOMEDIR 101727
6c8f12af 82 *
83 * arguments when moira creates a container (OU).
209367bd 84 * containers 0 8 machines/test/bottom description location contact USER 105316 2222 [none]
6c8f12af 85 *
86 * arguments when moira deletes a container (OU).
209367bd 87 * containers 8 0 machines/test/bottom description location contact USER 105316 2222 groupname
9cfe334f 88 *
6c8f12af 89 * arguments when moira modifies a container information (OU).
209367bd 90 * containers 8 8 machines/test/bottom description location contact USER 105316 2222 groupname machines/test/bottom description1 location contact USER 105316 2222 groupname
bbef4f93 91 *
92 * arguments when moira adds a machine from an OU
93 * table name, beforec, afterc, machine_name, container_name, mach_id, cnt_id
209367bd 94 * mcntmap 0 5 DAVIDT.MIT.EDU dttest/dttest1 76767 46 groupname
bbef4f93 95 *
96 * arguments when moira removes a machine from an OU
97 * table name, beforec, afterc, machine_name, container_name, mach_id, cnt_id
209367bd 98 * mcntmap 0 5 DAVIDT.MIT.EDU dttest/dttest1 76767 46 groupname
bbef4f93 99 *
cd9e6b16 100*/
5d0a7127 101#include <mit-copyright.h>
102#ifdef _WIN32
103#include <windows.h>
104#include <stdlib.h>
105#include <malloc.h>
106#include <lmaccess.h>
107#endif
f78c7eaf 108#include <hesiod.h>
cd9e6b16 109#include <string.h>
5d0a7127 110#include <ldap.h>
111#include <stdio.h>
112#include <moira.h>
113#include <moira_site.h>
cd9e6b16 114#include <mrclient.h>
5d0a7127 115#include <krb5.h>
116#include <krb.h>
117#include <gsssasl.h>
118#include <gssldap.h>
cd9e6b16 119#include "kpasswd.h"
120
121#ifdef _WIN32
122#ifndef ECONNABORTED
123#define ECONNABORTED WSAECONNABORTED
124#endif
125#ifndef ECONNREFUSED
126#define ECONNREFUSED WSAECONNREFUSED
127#endif
128#ifndef EHOSTUNREACH
129#define EHOSTUNREACH WSAEHOSTUNREACH
130#endif
131#define krb5_xfree free
0d958b3c 132#define F_OK 0
133#define sleep(A) Sleep(A * 1000);
cd9e6b16 134#endif /* _WIN32 */
5d0a7127 135
136#ifndef _WIN32
f78c7eaf 137#include <sys/types.h>
138#include <netinet/in.h>
139#include <arpa/nameser.h>
140#include <resolv.h>
5d0a7127 141#include <sys/utsname.h>
0d958b3c 142#include <unistd.h>
5d0a7127 143
f75f605a 144#define WINADCFG "/moira/winad/winad.cfg"
f78c7eaf 145#define strnicmp(A,B,C) strncasecmp(A,B,C)
cd9e6b16 146#define UCHAR unsigned char
147
5d0a7127 148#define UF_SCRIPT 0x0001
149#define UF_ACCOUNTDISABLE 0x0002
150#define UF_HOMEDIR_REQUIRED 0x0008
151#define UF_LOCKOUT 0x0010
152#define UF_PASSWD_NOTREQD 0x0020
153#define UF_PASSWD_CANT_CHANGE 0x0040
cd9e6b16 154#define UF_DONT_EXPIRE_PASSWD 0x10000
5d0a7127 155
156#define UF_TEMP_DUPLICATE_ACCOUNT 0x0100
157#define UF_NORMAL_ACCOUNT 0x0200
158#define UF_INTERDOMAIN_TRUST_ACCOUNT 0x0800
159#define UF_WORKSTATION_TRUST_ACCOUNT 0x1000
160#define UF_SERVER_TRUST_ACCOUNT 0x2000
161
909e0dc3 162#define OWNER_SECURITY_INFORMATION (0x00000001L)
163#define GROUP_SECURITY_INFORMATION (0x00000002L)
164#define DACL_SECURITY_INFORMATION (0x00000004L)
165#define SACL_SECURITY_INFORMATION (0x00000008L)
166
5d0a7127 167#ifndef BYTE
168#define BYTE unsigned char
169#endif
170typedef unsigned int DWORD;
171typedef unsigned long ULONG;
172
173typedef struct _GUID
174{
175 unsigned long Data1;
176 unsigned short Data2;
177 unsigned short Data3;
178 unsigned char Data4[8];
179} GUID;
180
181typedef struct _SID_IDENTIFIER_AUTHORITY {
182 BYTE Value[6];
183} SID_IDENTIFIER_AUTHORITY, *PSID_IDENTIFIER_AUTHORITY;
184
185typedef struct _SID {
186 BYTE Revision;
187 BYTE SubAuthorityCount;
188 SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
189 DWORD SubAuthority[512];
190} SID;
191#endif/*!WIN32*/
192
f75f605a 193#ifndef WINADCFG
194#define WINADCFG "winad.cfg"
195#endif
196
f78c7eaf 197#define AFS "/afs/"
198#define WINAFS "\\\\afs\\all\\"
199
cd9e6b16 200#define ADS_GROUP_TYPE_GLOBAL_GROUP 0x00000002
f78c7eaf 201#define ADS_GROUP_TYPE_DOMAIN_LOCAL_GROUP 0x00000004
202#define ADS_GROUP_TYPE_LOCAL_GROUP 0x00000004
203#define ADS_GROUP_TYPE_UNIVERSAL_GROUP 0x00000008
204#define ADS_GROUP_TYPE_SECURITY_ENABLED 0x80000000
cd9e6b16 205
206#define QUERY_VERSION -1
207#define PRIMARY_REALM "ATHENA.MIT.EDU"
208
5d0a7127 209#define SUBSTITUTE 1
210#define REPLACE 2
211
cd9e6b16 212#define USERS 0
213#define GROUPS 1
214
5d0a7127 215#define MEMBER_ADD 1
216#define MEMBER_REMOVE 2
217#define MEMBER_CHANGE_NAME 3
218#define MEMBER_ACTIVATE 4
219#define MEMBER_DEACTIVATE 5
cd9e6b16 220#define MEMBER_CREATE 6
5d0a7127 221
f78c7eaf 222#define MOIRA_ALL 0x0
223#define MOIRA_USERS 0x1
224#define MOIRA_KERBEROS 0x2
225#define MOIRA_STRINGS 0x4
226#define MOIRA_LISTS 0x8
227
89db421e 228#define CHECK_GROUPS 1
229#define CLEANUP_GROUPS 2
230
231#define AD_NO_GROUPS_FOUND -1
232#define AD_WRONG_GROUP_DN_FOUND -2
233#define AD_MULTIPLE_GROUPS_FOUND -3
234#define AD_INVALID_NAME -4
235#define AD_LDAP_FAILURE -5
236#define AD_INVALID_FILESYS -6
237#define AD_NO_ATTRIBUTE_FOUND -7
238#define AD_NO_OU_FOUND -8
239#define AD_NO_USER_FOUND -9
240
6c8f12af 241/* container arguments */
209367bd 242#define CONTAINER_NAME 0
243#define CONTAINER_DESC 1
244#define CONTAINER_LOCATION 2
245#define CONTAINER_CONTACT 3
246#define CONTAINER_TYPE 4
247#define CONTAINER_ID 5
248#define CONTAINER_ROWID 6
249#define CONTAINER_GROUP_NAME 7
6c8f12af 250
bbef4f93 251/*mcntmap arguments*/
252#define OU_MACHINE_NAME 0
253#define OU_CONTAINER_NAME 1
254#define OU_MACHINE_ID 2
255#define OU_CONTAINER_ID 3
209367bd 256#define OU_CONTAINER_GROUP 4
bbef4f93 257
5d0a7127 258typedef struct lk_entry {
259 int op;
260 int length;
261 int ber_value;
262 char *dn;
263 char *attribute;
264 char *value;
265 char *member;
266 char *type;
267 char *list;
268 struct lk_entry *next;
269} LK_ENTRY;
270
0d958b3c 271#define STOP_FILE "/moira/winad/nowinad"
272#define file_exists(file) (access((file), F_OK) == 0)
273
909e0dc3 274#define N_SD_BER_BYTES 5
5d0a7127 275#define LDAP_BERVAL struct berval
cd9e6b16 276#define MAX_SERVER_NAMES 32
277
909e0dc3 278#define HIDDEN_GROUP "HiddenGroup.g"
279#define HIDDEN_GROUP_WITH_ADMIN "HiddenGroupWithAdmin.g"
280#define NOT_HIDDEN_GROUP "NotHiddenGroup.g"
281#define NOT_HIDDEN_GROUP_WITH_ADMIN "NotHiddenGroupWithAdmin.g"
282
cd9e6b16 283#define ADD_ATTR(t, v, o) \
284 mods[n] = malloc(sizeof(LDAPMod)); \
285 mods[n]->mod_op = o; \
286 mods[n]->mod_type = t; \
287 mods[n++]->mod_values = v
5d0a7127 288
3abb4456 289#define DEL_ATTR(t, o) \
290 DelMods[i] = malloc(sizeof(LDAPMod)); \
291 DelMods[i]->mod_op = o; \
292 DelMods[i]->mod_type = t; \
293 DelMods[i++]->mod_values = NULL
294
295#define DOMAIN_SUFFIX "MIT.EDU"
296
5d0a7127 297LK_ENTRY *member_base = NULL;
cd9e6b16 298LK_ENTRY *sid_base = NULL;
299LK_ENTRY **sid_ptr = NULL;
0d958b3c 300static char tbl_buf[1024];
89db421e 301char kerberos_ou[] = "OU=kerberos,OU=moira";
302char contact_ou[] = "OU=strings,OU=moira";
303char user_ou[] = "OU=users,OU=moira";
304char group_ou_distribution[] = "OU=mail,OU=lists,OU=moira";
305char group_ou_root[] = "OU=lists,OU=moira";
306char group_ou_security[] = "OU=group,OU=lists,OU=moira";
307char group_ou_neither[] = "OU=special,OU=lists,OU=moira";
308char group_ou_both[] = "OU=mail,OU=group,OU=lists,OU=moira";
6c8f12af 309char orphans_machines_ou[] = "OU=Machines,OU=Orphans";
310char orphans_other_ou[] = "OU=Other,OU=Orphans";
909e0dc3 311char security_template_ou[] = "OU=security_templates";
5d0a7127 312char *whoami;
cd9e6b16 313char ldap_domain[256];
cd9e6b16 314int mr_connections = 0;
78af4e6e 315int callback_rc;
f78c7eaf 316char default_server[256];
bfb6f0ad 317static char tbl_buf[1024];
3abb4456 318int UseSFU30 = 0;
cd9e6b16 319
f78c7eaf 320extern int set_password(char *user, char *password, char *domain);
cd9e6b16 321
89db421e 322int ad_get_group(LDAP *ldap_handle, char *dn_path, char *group_name,
323 char *group_membership, char *MoiraId, char *attribute,
324 LK_ENTRY **linklist_base, int *linklist_count,
325 char *rFilter);
f78c7eaf 326void AfsToWinAfs(char* path, char* winPath);
327int ad_connect(LDAP **ldap_handle, char *ldap_domain, char *dn_path,
328 char *Win2kPassword, char *Win2kUser, char *default_server,
329 int connect_to_kdc);
330void ad_kdc_disconnect();
909e0dc3 331int BEREncodeSecurityBits(ULONG uBits, char *pBuffer);
bbef4f93 332int checkADname(LDAP *ldap_handle, char *dn_path, char *Name);
0d958b3c 333void check_winad(void);
89db421e 334int check_user(LDAP *ldap_handle, char *dn_path, char *UserName, char *MoiraId);
6c8f12af 335/* containers */
336int container_adupdate(LDAP *ldap_handle, char *dn_path, char *dName,
337 char *distinguishedName, int count, char **av);
338void container_check(LDAP *ldap_handle, char *dn_path, char *name);
339int container_create(LDAP *ldap_handle, char *dn_path, int count, char **av);
340int container_delete(LDAP *ldap_handle, char *dn_path, int count, char **av);
341int container_get_distinguishedName(LDAP *ldap_handle, char *dn_path,
342 char *distinguishedName, int count, char **av);
343void container_get_dn(char *src, char *dest);
344void container_get_name(char *src, char *dest);
345int container_move_objects(LDAP *ldap_handle, char *dn_path, char *dName);
346int container_rename(LDAP *ldap_handle, char *dn_path, int beforec, char **before,
347 int afterc, char **after);
348int container_update(LDAP *ldap_handle, char *dn_path, int beforec, char **before,
349 int afterc, char **after);
350
f75f605a 351int filesys_process(LDAP *ldap_handle, char *dn_path, char *fs_name,
352 char *fs_type, char *fs_pack, int operation);
909e0dc3 353int GetAceInfo(int ac, char **av, void *ptr);
f75f605a 354int get_group_membership(char *group_membership, char *group_ou,
355 int *security_flag, char **av);
5f7b0741 356int get_machine_ou(LDAP *ldap_handle, char *dn_path, char *member, char *machine_ou);
209367bd 357int Moira_container_group_create(char **after);
358int Moira_container_group_delete(char **before);
359int Moira_groupname_create(char *GroupName, char *ContainerName,
360 char *ContainerRowID);
361int Moira_container_group_update(char **before, char **after);
362int Moira_process_machine_container_group(char *MachineName, char* groupName,
363 int DeleteMachine);
364int Moira_addGroupToParent(char *origContainerName, char *GroupName);
365int Moira_getContainerGroup(int ac, char **av, void *ptr);
366int Moira_getGroupName(char *origContainerName, char *GroupName,
367 int ParentFlag);
368int Moira_setContainerGroup(char *ContainerName, char *GroupName);
909e0dc3 369int ProcessAce(LDAP *ldap_handle, char *dn_path, char *group_name, char *Type,
370 int UpdateGroup, int *ProcessGroup);
89db421e 371int process_group(LDAP *ldap_handle, char *dn_path, char *MoiraId,
372 char *group_name, char *group_ou, char *group_membership,
373 int group_security_flag, int type);
f75f605a 374int process_lists(int ac, char **av, void *ptr);
909e0dc3 375int ProcessGroupSecurity(LDAP *ldap_handle, char *dn_path, char *TargetGroupName,
376 int HiddenGroup, char *AceType, char *AceName);
3abb4456 377int ProcessMachineName(int ac, char **av, void *ptr);
cd9e6b16 378int user_create(int ac, char **av, void *ptr);
89db421e 379int user_change_status(LDAP *ldap_handle, char *dn_path,
380 char *user_name, char *MoiraId, int operation);
381int user_delete(LDAP *ldap_handle, char *dn_path,
382 char *u_name, char *MoiraId);
f75f605a 383int user_rename(LDAP *ldap_handle, char *dn_path, char *before_user_name,
89db421e 384 char *user_name);
f75f605a 385int user_update(LDAP *ldap_handle, char *dn_path, char *user_name,
3abb4456 386 char *uid, char *MitId, char *MoiraId, int State,
387 char *WinHomeDir, char *WinProfileDir);
89db421e 388void change_to_lower_case(char *ptr);
cd9e6b16 389int contact_create(LDAP *ld, char *bind_path, char *user, char *group_ou);
cd9e6b16 390int group_create(int ac, char **av, void *ptr);
f75f605a 391int group_delete(LDAP *ldap_handle, char *dn_path,
89db421e 392 char *group_name, char *group_membership, char *MoiraId);
f75f605a 393int group_rename(LDAP *ldap_handle, char *dn_path,
394 char *before_group_name, char *before_group_membership,
5a775f54 395 char *before_group_ou, int before_security_flag, char *before_desc,
f75f605a 396 char *after_group_name, char *after_group_membership,
89db421e 397 char *after_group_ou, int after_security_flag, char *after_desc,
398 char *MoiraId, char *filter);
bbef4f93 399int machine_check(LDAP *ldap_handle, char *dn_path, char *machine_name);
400int machine_GetMoiraContainer(int ac, char **av, void *ptr);
401int machine_get_moira_container(LDAP *ldap_handle, char *dn_path, char *machine_name, char *container_name);
402int machine_move_to_ou(LDAP *ldap_handle, char *dn_path, char *MoiraMachineName, char *DestinationOu);
89db421e 403int make_new_group(LDAP *ldap_handle, char *dn_path, char *MoiraId,
404 char *group_name, char *group_ou, char *group_membership,
405 int group_security_flag, int updateGroup);
cd9e6b16 406int member_list_build(int ac, char **av, void *ptr);
f75f605a 407int member_add(LDAP *ldap_handle, char *dn_path, char *group_name,
408 char *group_ou, char *group_membership,
89db421e 409 char *user_name, char *pUserOu, char *MoiraId);
78af4e6e 410int member_remove(LDAP *ldap_handle, char *dn_path, char *group_name,
f75f605a 411 char *group_ou, char *group_membership, char *user_name,
89db421e 412 char *pUserOu, char *MoiraId);
413int populate_group(LDAP *ldap_handle, char *dn_path, char *group_name,
414 char *group_ou, char *group_membership,
415 int group_security_flag, char *MoiraId);
3abb4456 416int SetHomeDirectory(LDAP *ldap_handle, char *user_name, char *DistinguishedName,
417 char *WinHomeDir, char *WinProfileDir,
418 char **homedir_v, char **winProfile_v,
419 char **drives_v, LDAPMod **mods,
420 int OpType, int n);
cd9e6b16 421int sid_update(LDAP *ldap_handle, char *dn_path);
3abb4456 422void SwitchSFU(LDAPMod **mods, int *UseSFU30, int n);
cd9e6b16 423int check_string(char *s);
bb52f279 424int check_container_name(char* s);
cd9e6b16 425void convert_b_to_a(char *string, UCHAR *binary, int length);
426int mr_connect_cl(char *server, char *client, int version, int auth);
427
6c8f12af 428void do_container(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
429 char **before, int beforec, char **after, int afterc);
f78c7eaf 430void do_filesys(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
431 char **before, int beforec, char **after, int afterc);
432void do_list(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
433 char **before, int beforec, char **after, int afterc);
434void do_user(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
cd9e6b16 435 char **before, int beforec, char **after, int afterc);
5d0a7127 436void do_member(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
cd9e6b16 437 char **before, int beforec, char **after, int afterc);
bbef4f93 438void do_mcntmap(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
439 char **before, int beforec, char **after, int afterc);
cd9e6b16 440int linklist_create_entry(char *attribute, char *value,
441 LK_ENTRY **linklist_entry);
5d0a7127 442int linklist_build(LDAP *ldap_handle, char *dn_path, char *search_exp,
cd9e6b16 443 char **attr_array, LK_ENTRY **linklist_base,
444 int *linklist_count);
5d0a7127 445void linklist_free(LK_ENTRY *linklist_base);
cd9e6b16 446
447int retrieve_attributes(LDAP *ldap_handle, LDAPMessage *ldap_entry,
448 char *distinguished_name, LK_ENTRY **linklist_current);
449int retrieve_entries(LDAP *ldap_handle, LDAPMessage *ldap_entry,
450 LK_ENTRY **linklist_base, int *linklist_count);
451int retrieve_values(LDAP *ldap_handle, LDAPMessage *ldap_entry,
452 char *Attribute, char *distinguished_name,
453 LK_ENTRY **linklist_current);
454
455int construct_newvalues(LK_ENTRY *linklist_base, int modvalue_count,
456 char *oldValue, char *newValue,
457 char ***modvalues, int type);
458void free_values(char **modvalues);
459
460int convert_domain_to_dn(char *domain, char **bind_path);
5d0a7127 461void get_distinguished_name(LDAP *ldap_handle, LDAPMessage *ldap_entry,
cd9e6b16 462 char *distinguished_name);
5d0a7127 463int moira_disconnect(void);
464int moira_connect(void);
465void print_to_screen(const char *fmt, ...);
3abb4456 466int GetMachineName(char *MachineName);
5d0a7127 467
468int main(int argc, char **argv)
469{
cd9e6b16 470 unsigned long rc;
471 int beforec;
472 int afterc;
cd9e6b16 473 int i;
cd9e6b16 474 char *table;
475 char **before;
476 char **after;
cd9e6b16 477 LDAP *ldap_handle;
5d0a7127 478 FILE *fptr;
f78c7eaf 479 char dn_path[256];
3abb4456 480 char temp[32];
cd9e6b16 481
5d0a7127 482 whoami = ((whoami = (char *)strrchr(argv[0], '/')) ? whoami+1 : argv[0]);
cd9e6b16 483
484 if (argc < 4)
485 {
486 com_err(whoami, 0, "%s", "argc < 4");
487 exit(1);
488 }
489 beforec = atoi(argv[2]);
490 afterc = atoi(argv[3]);
491
492 if (argc < (4 + beforec + afterc))
493 {
494 com_err(whoami, 0, "%s", "argc < (4 + breforec + afterc)");
495 exit(1);
496 }
497
498 table = argv[1];
499 before = &argv[4];
500 after = &argv[4 + beforec];
501
bfb6f0ad 502 for (i = 1; i < argc; i++)
0d958b3c 503 {
bfb6f0ad 504 strcat(tbl_buf, argv[i]);
505 strcat(tbl_buf, " ");
0d958b3c 506 }
bfb6f0ad 507 com_err(whoami, 0, "%s", tbl_buf);
508
0d958b3c 509 check_winad();
f75f605a 510
cd9e6b16 511 memset(ldap_domain, '\0', sizeof(ldap_domain));
3abb4456 512 memset(temp, '\0', sizeof(temp));
513 UseSFU30 = 0;
f75f605a 514 if ((fptr = fopen(WINADCFG, "r")) != NULL)
5d0a7127 515 {
3abb4456 516 if (fscanf(fptr, "%s\n", ldap_domain) != 0)
517 {
518 if (fscanf(fptr, "%s\n", temp) != 0)
519 {
520 if (!strcasecmp(temp, "SFU30"))
521 UseSFU30 = 1;
522 }
523 }
5d0a7127 524 fclose(fptr);
525 }
cd9e6b16 526 if (strlen(ldap_domain) == 0)
9db0b148 527 strcpy(ldap_domain, "win.mit.edu");
535f3d5e 528
529 /* zero trailing newline, if there is one. */
530 if (ldap_domain[strlen(ldap_domain) - 1] == '\n')
531 ldap_domain[strlen(ldap_domain) - 1] = '\0';
532
5d0a7127 533 initialize_sms_error_table();
534 initialize_krb_error_table();
cd9e6b16 535
f78c7eaf 536 memset(default_server, '\0', sizeof(default_server));
537 memset(dn_path, '\0', sizeof(dn_path));
89db421e 538 for (i = 0; i < 5; i++)
cd9e6b16 539 {
89db421e 540 if (!(rc = ad_connect(&ldap_handle, ldap_domain, dn_path, "", "", default_server, 1)))
541 break;
542 sleep(2);
543 }
544 if (rc)
545 {
546 critical_alert("incremental", "winad.incr cannot connect to any server in domain %s", ldap_domain);
cd9e6b16 547 exit(1);
548 }
cd9e6b16 549
9db0b148 550 for (i = 0; i < (int)strlen(table); i++)
551 table[i] = tolower(table[i]);
5d0a7127 552 if (!strcmp(table, "users"))
f78c7eaf 553 do_user(ldap_handle, dn_path, ldap_domain, before, beforec, after,
554 afterc);
5d0a7127 555 else if (!strcmp(table, "list"))
cd9e6b16 556 do_list(ldap_handle, dn_path, ldap_domain, before, beforec, after,
557 afterc);
5d0a7127 558 else if (!strcmp(table, "imembers"))
cd9e6b16 559 do_member(ldap_handle, dn_path, ldap_domain, before, beforec, after,
560 afterc);
cd9e6b16 561 else if (!strcmp(table, "filesys"))
f78c7eaf 562 do_filesys(ldap_handle, dn_path, ldap_domain, before, beforec, after,
563 afterc);
6c8f12af 564 else if (!strcmp(table, "containers"))
565 do_container(ldap_handle, dn_path, ldap_domain, before, beforec, after,
566 afterc);
bbef4f93 567 else if (!strcmp(table, "mcntmap"))
568 do_mcntmap(ldap_handle, dn_path, ldap_domain, before, beforec, after,
569 afterc);
f78c7eaf 570 ad_kdc_disconnect();
5d0a7127 571 rc = ldap_unbind_s(ldap_handle);
5d0a7127 572 exit(0);
573}
574
bbef4f93 575void do_mcntmap(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
576 char **before, int beforec, char **after, int afterc)
577{
578 char MoiraContainerName[128];
579 char ADContainerName[128];
3abb4456 580 char MachineName[1024];
581 char OriginalMachineName[1024];
bbef4f93 582 long rc;
209367bd 583 int DeleteMachine;
584 char MoiraContainerGroup[64];
bbef4f93 585
209367bd 586 DeleteMachine = 0;
bbef4f93 587 memset(ADContainerName, '\0', sizeof(ADContainerName));
209367bd 588 memset(MoiraContainerName, '\0', sizeof(MoiraContainerName));
589
bbef4f93 590 if ((beforec == 0) && (afterc == 0))
591 return;
592
593 if (rc = moira_connect())
594 {
595 critical_alert("AD incremental",
596 "Error contacting Moira server : %s",
597 error_message(rc));
598 return;
599 }
600
601 if ((beforec != 0) && (afterc == 0)) /*remove a machine*/
602 {
3abb4456 603 strcpy(OriginalMachineName, before[OU_MACHINE_NAME]);
bbef4f93 604 strcpy(MachineName, before[OU_MACHINE_NAME]);
3abb4456 605 strcpy(MoiraContainerGroup, before[OU_CONTAINER_GROUP]);
606 DeleteMachine = 1;
607 com_err(whoami, 0, "removing machine %s from %s", OriginalMachineName, before[OU_CONTAINER_NAME]);
bbef4f93 608 }
609 else if ((beforec == 0) && (afterc != 0)) /*add a machine*/
610 {
3abb4456 611 strcpy(OriginalMachineName, after[OU_MACHINE_NAME]);
bbef4f93 612 strcpy(MachineName, after[OU_MACHINE_NAME]);
3abb4456 613 strcpy(MoiraContainerGroup, after[OU_CONTAINER_GROUP]);
614 com_err(whoami, 0, "adding machine %s to container %s", OriginalMachineName, after[OU_CONTAINER_NAME]);
bbef4f93 615 }
616 else
209367bd 617 {
3abb4456 618 moira_disconnect();
bbef4f93 619 return;
209367bd 620 }
bbef4f93 621
3abb4456 622 rc = GetMachineName(MachineName);
623 if (strlen(MachineName) == 0)
624 {
625 moira_disconnect();
626 com_err(whoami, 0, "Unable to find alais for machine %s in Moira", OriginalMachineName);
627 return;
628 }
209367bd 629 Moira_process_machine_container_group(MachineName, MoiraContainerGroup,
630 DeleteMachine);
bbef4f93 631 if (machine_check(ldap_handle, dn_path, MachineName))
632 {
3abb4456 633 com_err(whoami, 0, "machine %s (alias %s) not found in AD.", OriginalMachineName, MachineName);
634 moira_disconnect();
bbef4f93 635 return;
636 }
209367bd 637 memset(MoiraContainerName, '\0', sizeof(MoiraContainerName));
bbef4f93 638 machine_get_moira_container(ldap_handle, dn_path, MachineName, MoiraContainerName);
639 if (strlen(MoiraContainerName) == 0)
640 {
3abb4456 641 com_err(whoami, 0, "machine %s (alias %s) container not found in Moira - moving to orphans OU.",
642 OriginalMachineName, MachineName);
bbef4f93 643 machine_move_to_ou(ldap_handle, dn_path, MachineName, orphans_machines_ou);
3abb4456 644 moira_disconnect();
bbef4f93 645 return;
646 }
647 container_get_dn(MoiraContainerName, ADContainerName);
648 if (MoiraContainerName[strlen(MoiraContainerName) - 1] != '/')
649 strcat(MoiraContainerName, "/");
650 container_check(ldap_handle, dn_path, MoiraContainerName);
651 machine_move_to_ou(ldap_handle, dn_path, MachineName, ADContainerName);
209367bd 652 moira_disconnect();
bbef4f93 653 return;
654}
655
6c8f12af 656void do_container(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
657 char **before, int beforec, char **after, int afterc)
658{
209367bd 659 long rc;
6c8f12af 660
661 if ((beforec == 0) && (afterc == 0))
662 return;
663
209367bd 664 if (rc = moira_connect())
665 {
666 critical_alert("AD incremental", "Error contacting Moira server : %s",
667 error_message(rc));
668 return;
669 }
670
6c8f12af 671 if ((beforec != 0) && (afterc == 0)) /*delete a new container*/
672 {
673 com_err(whoami, 0, "deleting container %s", before[CONTAINER_NAME]);
674 container_delete(ldap_handle, dn_path, beforec, before);
209367bd 675 Moira_container_group_delete(before);
676 moira_disconnect();
6c8f12af 677 return;
678 }
679 if ((beforec == 0) && (afterc != 0)) /*create a container*/
680 {
9cfe334f 681 com_err(whoami, 0, "creating container %s", after[CONTAINER_NAME]);
6c8f12af 682 container_check(ldap_handle, dn_path, after[CONTAINER_NAME]);
683 container_create(ldap_handle, dn_path, afterc, after);
209367bd 684 Moira_container_group_create(after);
685 moira_disconnect();
6c8f12af 686 return;
687 }
688
689 if (strcasecmp(before[CONTAINER_NAME], after[CONTAINER_NAME]))
690 {
691 com_err(whoami, 0, "renaming container %s to %s", before[CONTAINER_NAME], after[CONTAINER_NAME]);
692 container_rename(ldap_handle, dn_path, beforec, before, afterc, after);
209367bd 693 Moira_container_group_update(before, after);
694 moira_disconnect();
6c8f12af 695 return;
696 }
9cfe334f 697 com_err(whoami, 0, "updating container %s information", after[CONTAINER_NAME]);
6c8f12af 698 container_update(ldap_handle, dn_path, beforec, before, afterc, after);
209367bd 699 Moira_container_group_update(before, after);
700 moira_disconnect();
6c8f12af 701 return;
702}
703
f78c7eaf 704void do_filesys(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
705 char **before, int beforec, char **after, int afterc)
706{
707 long rc;
708 char *av[3];
709 char *call_args[7];
710 int acreate;
711 int atype;
712 int bcreate;
713 int btype;
f75f605a 714 int abort_flag;
f78c7eaf 715
f75f605a 716 abort_flag = 0;
f78c7eaf 717
718 if (afterc < FS_CREATE)
719 atype = acreate = 0;
720 else
721 {
722 atype = !strcmp(after[FS_TYPE], "AFS");
723 acreate = atoi(after[FS_CREATE]);
724 }
725
726 if (beforec < FS_CREATE)
727 {
728 if (acreate == 0 || atype == 0)
729 goto cleanup;
730 com_err(whoami, 0, "Processing filesys %s", after[FS_NAME]);
f75f605a 731 abort_flag = 0;
732 while (1)
733 {
734 if ((rc = filesys_process(ldap_handle, dn_path, after[FS_NAME],
735 after[FS_TYPE], after[FS_PACK], LDAP_MOD_ADD)) != LDAP_NO_SUCH_OBJECT)
736 {
737 if (rc != LDAP_SUCCESS)
738 com_err(whoami, 0, "Couldn't process filesys %s", after[FS_NAME]);
739 break;
740 }
741 if (abort_flag == 1)
742 break;
743 sleep(1);
744 abort_flag = 1;
745 if (rc = moira_connect())
746 {
747 critical_alert("AD incremental",
748 "Error contacting Moira server : %s",
749 error_message(rc));
750 return;
751 }
752 av[0] = after[FS_NAME];
753 call_args[0] = (char *)ldap_handle;
754 call_args[1] = dn_path;
89db421e 755 call_args[2] = "";
f75f605a 756 call_args[3] = NULL;
757 sid_base = NULL;
758 sid_ptr = &sid_base;
5b8457c5 759 callback_rc = 0;
f75f605a 760 if (rc = mr_query("get_user_account_by_login", 1, av, user_create,
761 call_args))
762 {
763 moira_disconnect();
764 com_err(whoami, 0, "Couldn't process filesys %s", after[FS_NAME]);
765 break;
766 }
5b8457c5 767 if (callback_rc)
768 {
769 moira_disconnect();
770 com_err(whoami, 0, "Couldn't process filesys %s", after[FS_NAME]);
771 break;
772 }
f75f605a 773 if (sid_base != NULL)
774 {
775 sid_update(ldap_handle, dn_path);
776 linklist_free(sid_base);
777 sid_base = NULL;
778 }
779 moira_disconnect();
780 }
f78c7eaf 781 goto cleanup;
782 }
783
784 btype = !strcmp(before[FS_TYPE], "AFS");
785 bcreate = atoi(before[FS_CREATE]);
786 if (afterc < FS_CREATE)
787 {
788 if (btype && bcreate)
789 {
f75f605a 790 if (rc = filesys_process(ldap_handle, dn_path, before[FS_NAME],
791 before[FS_TYPE], before[FS_PACK], LDAP_MOD_DELETE))
f78c7eaf 792 {
f75f605a 793 com_err(whoami, 0, "Couldn't delete filesys %s", before[FS_NAME]);
f78c7eaf 794 }
795 }
f75f605a 796 return;
f78c7eaf 797 }
798
799 if (!acreate)
f75f605a 800 return;
f78c7eaf 801
802 if (!atype && !btype)
803 {
804 if (strcmp(before[FS_TYPE], "ERR") || strcmp(after[FS_TYPE], "ERR"))
805 {
f75f605a 806 com_err(whoami, 0, "Filesystem %s or %s is not AFS",
807 before[FS_NAME], after[FS_NAME]);
808 return;
f78c7eaf 809 }
810 }
811 com_err(whoami, 0, "Processing filesys %s", after[FS_NAME]);
f75f605a 812 abort_flag = 0;
813 while (1)
814 {
815 if ((rc = filesys_process(ldap_handle, dn_path, after[FS_NAME],
816 after[FS_TYPE], after[FS_PACK], LDAP_MOD_ADD)) != LDAP_NO_SUCH_OBJECT)
817 {
818 if (rc != LDAP_SUCCESS)
819 com_err(whoami, 0, "Couldn't process filesys %s", after[FS_NAME]);
820 break;
821 }
822 if (abort_flag == 1)
823 break;
824 sleep(1);
825 abort_flag = 1;
826 if (rc = moira_connect())
827 {
828 critical_alert("AD incremental",
829 "Error contacting Moira server : %s",
830 error_message(rc));
831 return;
832 }
833 av[0] = after[FS_NAME];
834 call_args[0] = (char *)ldap_handle;
835 call_args[1] = dn_path;
89db421e 836 call_args[2] = "";
f75f605a 837 call_args[3] = NULL;
838 sid_base = NULL;
839 sid_ptr = &sid_base;
5b8457c5 840 callback_rc = 0;
f75f605a 841 if (rc = mr_query("get_user_account_by_login", 1, av, user_create,
842 call_args))
843 {
844 moira_disconnect();
845 com_err(whoami, 0, "Couldn't process filesys %s", after[FS_NAME]);
846 break;
847 }
5b8457c5 848 if (callback_rc)
849 {
850 moira_disconnect();
851 com_err(whoami, 0, "Couldn't process filesys %s", after[FS_NAME]);
852 break;
853 }
f75f605a 854 if (sid_base != NULL)
855 {
856 sid_update(ldap_handle, dn_path);
857 linklist_free(sid_base);
858 sid_base = NULL;
859 }
860 moira_disconnect();
861 }
862
f78c7eaf 863cleanup:
f78c7eaf 864 return;
865}
89db421e 866
867#define L_LIST_DESC 9
868#define L_LIST_ID 10
869
cd9e6b16 870void do_list(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
871 char **before, int beforec, char **after, int afterc)
5d0a7127 872{
89db421e 873 int updateGroup;
909e0dc3 874 int ProcessGroup;
f75f605a 875 long rc;
89db421e 876 char group_membership[6];
877 char list_id[32];
f75f605a 878 int security_flag;
89db421e 879 char filter[128];
f75f605a 880 char group_ou[256];
89db421e 881 char before_list_id[32];
f75f605a 882 char before_group_membership[1];
883 int before_security_flag;
884 char before_group_ou[256];
f75f605a 885 LK_ENTRY *ptr = NULL;
9db0b148 886
887 if (beforec == 0 && afterc == 0)
888 return;
889
89db421e 890 memset(list_id, '\0', sizeof(list_id));
891 memset(before_list_id, '\0', sizeof(before_list_id));
892 memset(before_group_ou, '\0', sizeof(before_group_ou));
893 memset(before_group_membership, '\0', sizeof(before_group_membership));
894 memset(group_ou, '\0', sizeof(group_ou));
895 memset(group_membership, '\0', sizeof(group_membership));
896 updateGroup = 0;
897
898 if (beforec > L_GID)
899 {
900 if (beforec < L_LIST_ID)
901 return;
902 if (beforec > L_LIST_DESC)
903 {
904 strcpy(before_list_id, before[L_LIST_ID]);
905 }
f75f605a 906 before_security_flag = 0;
f75f605a 907 get_group_membership(before_group_membership, before_group_ou, &before_security_flag, before);
908 }
89db421e 909 if (afterc > L_GID)
f75f605a 910 {
89db421e 911 if (afterc < L_LIST_ID)
912 return;
913 if (afterc > L_LIST_DESC)
914 {
915 strcpy(list_id, before[L_LIST_ID]);
916 }
f75f605a 917 security_flag = 0;
f75f605a 918 get_group_membership(group_membership, group_ou, &security_flag, after);
919 }
89db421e 920
921 if ((beforec == 0) && (afterc == 0)) /*this case should never happen*/
f75f605a 922 return;
cd9e6b16 923
89db421e 924 updateGroup = 0;
925 if (beforec)
cd9e6b16 926 {
89db421e 927 updateGroup = 1;
928 if ((rc = process_group(ldap_handle, dn_path, before_list_id, before[L_NAME],
929 before_group_ou, before_group_membership,
930 before_security_flag, CHECK_GROUPS)))
931 {
932 if (rc == AD_NO_GROUPS_FOUND)
933 updateGroup = 0;
934 else
f75f605a 935 {
89db421e 936 if ((rc == AD_WRONG_GROUP_DN_FOUND) || (rc == AD_MULTIPLE_GROUPS_FOUND))
937 {
938 rc = process_group(ldap_handle, dn_path, before_list_id, before[L_NAME],
939 before_group_ou, before_group_membership,
940 before_security_flag, CLEANUP_GROUPS);
941 }
942 if ((rc != AD_NO_GROUPS_FOUND) && (rc != 0))
f75f605a 943 {
89db421e 944 com_err(whoami, 0, "Could not change list name from %s to %s",
945 before[L_NAME], after[L_NAME]);
f75f605a 946 return;
947 }
89db421e 948 if (rc == AD_NO_GROUPS_FOUND)
949 updateGroup = 0;
950 }
951 }
952 }
953
954 if ((beforec != 0) && (afterc != 0))
955 {
956 if (((strcmp(after[L_NAME], before[L_NAME])) ||
957 ((!strcmp(after[L_NAME], before[L_NAME])) &&
958 (strcmp(before_group_ou, group_ou)))) &&
959 (updateGroup == 1))
960 {
961 com_err(whoami, 0, "Changing list name from %s to %s",
962 before[L_NAME], after[L_NAME]);
963 if ((strlen(before_group_ou) == 0) || (strlen(before_group_membership) == 0) ||
964 (strlen(group_ou) == 0) || (strlen(group_membership) == 0))
965 {
966 com_err(whoami, 0, "%s", "couldn't find the group OU's");
967 return;
968 }
969 memset(filter, '\0', sizeof(filter));
970 if ((rc = group_rename(ldap_handle, dn_path,
971 before[L_NAME], before_group_membership,
972 before_group_ou, before_security_flag, before[L_LIST_DESC],
973 after[L_NAME], group_membership,
974 group_ou, security_flag, after[L_LIST_DESC],
975 list_id, filter)))
976 {
977 if (rc != AD_NO_GROUPS_FOUND)
f75f605a 978 {
89db421e 979 com_err(whoami, 0, "Could not change list name from %s to %s",
980 before[L_NAME], after[L_NAME]);
f75f605a 981 return;
982 }
89db421e 983 updateGroup = 0;
f75f605a 984 }
89db421e 985 beforec = 0;
f75f605a 986 }
987 else
89db421e 988 beforec = 0;
cd9e6b16 989 }
990
89db421e 991 if (beforec)
984c91b7 992 {
f75f605a 993 if ((strlen(before_group_ou) == 0) || (strlen(before_group_membership) == 0))
984c91b7 994 {
f75f605a 995 com_err(whoami, 0, "couldn't find the group OU for group %s", before[L_NAME]);
996 return;
997 }
984c91b7 998 com_err(whoami, 0, "Deleting group %s", before[L_NAME]);
89db421e 999 rc = group_delete(ldap_handle, dn_path, before[L_NAME],
1000 before_group_membership, before_list_id);
f75f605a 1001 return;
5d0a7127 1002 }
89db421e 1003 if (afterc)
5d0a7127 1004 {
89db421e 1005 if (!updateGroup)
1006 {
1007 com_err(whoami, 0, "Creating group %s", after[L_NAME]);
1008 if (rc = process_group(ldap_handle, dn_path, list_id, after[L_NAME],
1009 group_ou, group_membership,
1010 security_flag, CHECK_GROUPS))
1011 {
1012 if (rc != AD_NO_GROUPS_FOUND)
1013 {
1014 if ((rc == AD_WRONG_GROUP_DN_FOUND) || (rc == AD_MULTIPLE_GROUPS_FOUND))
1015 {
1016 rc = process_group(ldap_handle, dn_path, list_id, after[L_NAME],
1017 group_ou, group_membership,
1018 security_flag, CLEANUP_GROUPS);
1019 }
1020 if (rc)
1021 {
1022 com_err(whoami, 0, "Could not create list %s", after[L_NAME]);
1023 return;
1024 }
1025 }
1026 }
1027 }
1028 else
1029 com_err(whoami, 0, "Updating group %s information", after[L_NAME]);
cd9e6b16 1030
f75f605a 1031 if (rc = moira_connect())
1032 {
1033 critical_alert("AD incremental",
1034 "Error contacting Moira server : %s",
1035 error_message(rc));
1036 return;
1037 }
1038
909e0dc3 1039 ProcessGroup = 0;
1040 if (ProcessAce(ldap_handle, dn_path, after[L_NAME], "LIST", 0, &ProcessGroup))
1041 return;
1042 if (ProcessGroup)
1043 {
1044 if (ProcessAce(ldap_handle, dn_path, after[L_NAME], "LIST", 1, &ProcessGroup))
1045 return;
1046 }
89db421e 1047 if (make_new_group(ldap_handle, dn_path, list_id, after[L_NAME],
1048 group_ou, group_membership, security_flag, updateGroup))
cd9e6b16 1049 {
f75f605a 1050 moira_disconnect();
f75f605a 1051 return;
cd9e6b16 1052 }
89db421e 1053 if (atoi(after[L_ACTIVE]))
cd9e6b16 1054 {
89db421e 1055 populate_group(ldap_handle, dn_path, after[L_NAME], group_ou,
1056 group_membership, security_flag, list_id);
cd9e6b16 1057 }
f75f605a 1058 moira_disconnect();
5d0a7127 1059 }
f75f605a 1060 return;
5d0a7127 1061}
1062
f75f605a 1063#define LM_EXTRA_ACTIVE (LM_END)
1064#define LM_EXTRA_PUBLIC (LM_END+1)
1065#define LM_EXTRA_HIDDEN (LM_END+2)
1066#define LM_EXTRA_MAILLIST (LM_END+3)
1067#define LM_EXTRA_GROUP (LM_END+4)
1068#define LM_EXTRA_GID (LM_END+5)
89db421e 1069#define LMN_LIST_ID (LM_END+6)
1070#define LM_LIST_ID (LM_END+7)
1071#define LM_USER_ID (LM_END+8)
1072#define LM_EXTRA_END (LM_END+9)
984c91b7 1073
5d0a7127 1074void do_member(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
cd9e6b16 1075 char **before, int beforec, char **after, int afterc)
5d0a7127 1076{
cd9e6b16 1077 char group_name[128];
1078 char user_name[128];
9db0b148 1079 char user_type[128];
89db421e 1080 char moira_list_id[32];
1081 char moira_user_id[32];
f75f605a 1082 char group_membership[1];
f75f605a 1083 char group_ou[256];
5f7b0741 1084 char machine_ou[256];
f75f605a 1085 char *args[16];
1086 char **ptr;
89db421e 1087 char *av[7];
1088 char *call_args[7];
f75f605a 1089 char *pUserOu;
89db421e 1090 int security_flag;
1091 int rc;
909e0dc3 1092 int ProcessGroup;
f75f605a 1093
1094 pUserOu = NULL;
1095 ptr = NULL;
89db421e 1096 memset(moira_list_id, '\0', sizeof(moira_list_id));
1097 memset(moira_user_id, '\0', sizeof(moira_user_id));
5d0a7127 1098 if (afterc)
1099 {
89db421e 1100 if (afterc < LM_EXTRA_GID)
f75f605a 1101 return;
984c91b7 1102 if (!atoi(after[LM_EXTRA_ACTIVE]))
cd9e6b16 1103 return;
f75f605a 1104 ptr = after;
89db421e 1105 if (!strcasecmp(ptr[LM_TYPE], "LIST"))
1106 return;
984c91b7 1107 strcpy(user_name, after[LM_MEMBER]);
1108 strcpy(group_name, after[LM_LIST]);
1109 strcpy(user_type, after[LM_TYPE]);
5f7b0741 1110 if (!strcasecmp(ptr[LM_TYPE], "MACHINE"))
1111 {
1112 if (afterc > LM_EXTRA_GROUP)
1113 {
f7c496a6 1114 strcpy(moira_list_id, after[LMN_LIST_ID]);
1115 strcpy(moira_user_id, after[LM_LIST_ID]);
5f7b0741 1116 }
1117 }
1118 else if (!strcasecmp(ptr[LM_TYPE], "USER"))
89db421e 1119 {
1120 if (afterc > LMN_LIST_ID)
1121 {
1122 strcpy(moira_list_id, after[LM_LIST_ID]);
1123 strcpy(moira_user_id, after[LM_USER_ID]);
1124 }
1125 }
1126 else
1127 {
1128 if (afterc > LM_EXTRA_GID)
1129 strcpy(moira_list_id, after[LMN_LIST_ID]);
1130 }
5d0a7127 1131 }
1132 else if (beforec)
1133 {
89db421e 1134 if (beforec < LM_EXTRA_GID)
f75f605a 1135 return;
984c91b7 1136 if (!atoi(before[LM_EXTRA_ACTIVE]))
9db0b148 1137 return;
f75f605a 1138 ptr = before;
89db421e 1139 if (!strcasecmp(ptr[LM_TYPE], "LIST"))
1140 return;
984c91b7 1141 strcpy(user_name, before[LM_MEMBER]);
1142 strcpy(group_name, before[LM_LIST]);
1143 strcpy(user_type, before[LM_TYPE]);
5f7b0741 1144 if (!strcasecmp(ptr[LM_TYPE], "MACHINE"))
1145 {
1146 if (beforec > LM_EXTRA_GROUP)
1147 {
f7c496a6 1148 strcpy(moira_list_id, before[LMN_LIST_ID]);
1149 strcpy(moira_user_id, before[LM_LIST_ID]);
5f7b0741 1150 }
1151 }
1152 else if (!strcasecmp(ptr[LM_TYPE], "USER"))
89db421e 1153 {
1154 if (beforec > LMN_LIST_ID)
1155 {
1156 strcpy(moira_list_id, before[LM_LIST_ID]);
1157 strcpy(moira_user_id, before[LM_USER_ID]);
1158 }
1159 }
1160 else
1161 {
1162 if (beforec > LM_EXTRA_GID)
1163 strcpy(moira_list_id, before[LMN_LIST_ID]);
1164 }
5d0a7127 1165 }
cd9e6b16 1166
f75f605a 1167 if (ptr == NULL)
1168 return;
1169
1170 args[L_NAME] = ptr[LM_LIST];
1171 args[L_ACTIVE] = ptr[LM_EXTRA_ACTIVE];
1172 args[L_PUBLIC] = ptr[LM_EXTRA_PUBLIC];
1173 args[L_HIDDEN] = ptr[LM_EXTRA_HIDDEN];
1174 args[L_MAILLIST] = ptr[LM_EXTRA_MAILLIST];
1175 args[L_GROUP] = ptr[LM_EXTRA_GROUP];
1176 args[L_GID] = ptr[LM_EXTRA_GID];
1177
1178 security_flag = 0;
1179 memset(group_ou, '\0', sizeof(group_ou));
1180 get_group_membership(group_membership, group_ou, &security_flag, args);
1181 if (strlen(group_ou) == 0)
cd9e6b16 1182 {
f75f605a 1183 com_err(whoami, 0, "couldn't find the group OU for group %s", group_name);
cd9e6b16 1184 return;
1185 }
89db421e 1186 if (rc = process_group(ldap_handle, dn_path, moira_list_id, group_name, group_ou, group_membership, security_flag, CHECK_GROUPS))
1187 {
1188 if (rc != AD_NO_GROUPS_FOUND)
1189 {
1190 if (rc = process_group(ldap_handle, dn_path, moira_list_id, group_name, group_ou, group_membership, security_flag, CLEANUP_GROUPS))
1191 {
1192 if (rc != AD_NO_GROUPS_FOUND)
1193 {
1194 if (afterc)
1195 com_err(whoami, 0, "Couldn't add %s to group %s - unable to process group", user_name, group_name);
1196 else
c0bd7667 1197 com_err(whoami, 0, "Couldn't remove %s from group %s - unable to process group", user_name, group_name);
89db421e 1198 return;
1199 }
1200 }
1201 }
1202 }
1203 if (rc == AD_NO_GROUPS_FOUND)
1204 {
1205 if (rc = moira_connect())
1206 {
1207 critical_alert("AD incremental",
1208 "Error contacting Moira server : %s",
1209 error_message(rc));
1210 return;
1211 }
f75f605a 1212
89db421e 1213 com_err(whoami, 0, "creating group %s", group_name);
909e0dc3 1214 ProcessGroup = 0;
1215 if (ProcessAce(ldap_handle, dn_path, ptr[LM_LIST], "LIST", 0, &ProcessGroup))
1216 return;
1217 if (ProcessGroup)
1218 {
1219 if (ProcessAce(ldap_handle, dn_path, ptr[LM_LIST], "LIST", 1, &ProcessGroup))
1220 return;
1221 }
89db421e 1222 if (make_new_group(ldap_handle, dn_path, moira_list_id, ptr[LM_LIST],
1223 group_ou, group_membership, security_flag, 0))
1224 {
1225 moira_disconnect();
1226 return;
1227 }
1228 if (atoi(ptr[LM_EXTRA_ACTIVE]))
1229 {
1230 populate_group(ldap_handle, dn_path, ptr[LM_LIST], group_ou,
1231 group_membership, security_flag, moira_list_id);
1232 }
1233 moira_disconnect();
1234 }
f75f605a 1235 rc = 0;
1236 if (beforec)
1237 {
89db421e 1238 com_err(whoami, 0, "removing user %s from list %s", user_name, group_name);
f75f605a 1239 pUserOu = user_ou;
5f7b0741 1240 if (!strcasecmp(ptr[LM_TYPE], "MACHINE"))
1241 {
1242 memset(machine_ou, '\0', sizeof(machine_ou));
1243 if (get_machine_ou(ldap_handle, dn_path, ptr[LM_MEMBER], machine_ou))
1244 return;
1245 pUserOu = machine_ou;
1246 }
f75f605a 1247 if (!strcasecmp(ptr[LM_TYPE], "STRING"))
cd9e6b16 1248 {
f75f605a 1249 if (contact_create(ldap_handle, dn_path, ptr[LM_MEMBER], contact_ou))
1250 return;
1251 pUserOu = contact_ou;
1252 }
1253 else if (!strcasecmp(ptr[LM_TYPE], "KERBEROS"))
1254 {
1255 if (contact_create(ldap_handle, dn_path, ptr[LM_MEMBER], kerberos_ou))
1256 return;
1257 pUserOu = kerberos_ou;
1258 }
89db421e 1259 if (rc = member_remove(ldap_handle, dn_path, group_name,
1260 group_ou, group_membership, ptr[LM_MEMBER],
1261 pUserOu, moira_list_id))
c0bd7667 1262 com_err(whoami, 0, "couldn't remove %s from group %s", user_name, group_name);
89db421e 1263 return;
f75f605a 1264 }
89db421e 1265
1266 com_err(whoami, 0, "Adding %s to list %s", user_name, group_name);
1267 pUserOu = user_ou;
5f7b0741 1268
1269 if (!strcasecmp(ptr[LM_TYPE], "MACHINE"))
1270 {
1271 memset(machine_ou, '\0', sizeof(machine_ou));
1272 if (get_machine_ou(ldap_handle, dn_path, ptr[LM_MEMBER], machine_ou))
1273 return;
1274 pUserOu = machine_ou;
1275 }
1276 else if (!strcasecmp(ptr[LM_TYPE], "STRING"))
f75f605a 1277 {
89db421e 1278 if (contact_create(ldap_handle, dn_path, ptr[LM_MEMBER], contact_ou))
f75f605a 1279 return;
89db421e 1280 pUserOu = contact_ou;
1281 }
1282 else if (!strcasecmp(ptr[LM_TYPE], "KERBEROS"))
1283 {
1284 if (contact_create(ldap_handle, dn_path, ptr[LM_MEMBER], kerberos_ou))
1285 return;
1286 pUserOu = kerberos_ou;
1287 }
1288 else if (!strcasecmp(ptr[LM_TYPE], "USER"))
1289 {
1290 if ((rc = check_user(ldap_handle, dn_path, ptr[LM_MEMBER],
1291 moira_user_id)) == AD_NO_USER_FOUND)
f75f605a 1292 {
89db421e 1293 if (rc = moira_connect())
1294 {
1295 critical_alert("AD incremental",
1296 "Error connection to Moira : %s",
1297 error_message(rc));
1298 return;
1299 }
1300 com_err(whoami, 0, "creating user %s", after[U_NAME]);
1301 av[0] = ptr[LM_MEMBER];
1302 call_args[0] = (char *)ldap_handle;
1303 call_args[1] = dn_path;
1304 call_args[2] = moira_user_id;
1305 call_args[3] = NULL;
1306 sid_base = NULL;
1307 sid_ptr = &sid_base;
1308 callback_rc = 0;
1309 if (rc = mr_query("get_user_account_by_login", 1, av, user_create,
1310 call_args))
1311 {
1312 moira_disconnect();
1313 com_err(whoami, 0, "couldn't create user %s : %s",
1314 ptr[LM_MEMBER], error_message(rc));
1315 return;
1316 }
1317 if (callback_rc)
1318 {
1319 moira_disconnect();
1320 com_err(whoami, 0, "couldn't create user %s", ptr[LM_MEMBER]);
1321 return;
1322 }
1323 sleep(1);
1324 if (sid_base != NULL)
1325 {
1326 sid_update(ldap_handle, dn_path);
1327 linklist_free(sid_base);
1328 }
f75f605a 1329 }
89db421e 1330 else
f75f605a 1331 {
89db421e 1332 if (rc != 0)
f75f605a 1333 return;
cd9e6b16 1334 }
89db421e 1335 pUserOu = user_ou;
cd9e6b16 1336 }
89db421e 1337
1338 if (rc = member_add(ldap_handle, dn_path, group_name,
1339 group_ou, group_membership, ptr[LM_MEMBER],
1340 pUserOu, moira_list_id))
cd9e6b16 1341 {
89db421e 1342 com_err(whoami, 0, "couldn't add %s to group %s", user_name, group_name);
f75f605a 1343 }
1344 return;
5d0a7127 1345}
1346
cd9e6b16 1347
3abb4456 1348#define U_USER_ID 10
1349#define U_HOMEDIR 11
1350#define U_PROFILEDIR 12
89db421e 1351
f78c7eaf 1352void do_user(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
1353 char **before, int beforec, char **after,
cd9e6b16 1354 int afterc)
5d0a7127 1355{
984c91b7 1356 int rc;
89db421e 1357 char *av[7];
1358 char after_user_id[32];
1359 char before_user_id[32];
1360 char *call_args[7];
984c91b7 1361
5b8457c5 1362 if ((beforec == 0) && (afterc == 0))
984c91b7 1363 return;
1364
89db421e 1365 memset(after_user_id, '\0', sizeof(after_user_id));
1366 memset(before_user_id, '\0', sizeof(before_user_id));
1367 if (beforec > U_USER_ID)
1368 strcpy(before_user_id, before[U_USER_ID]);
1369 if (afterc > U_USER_ID)
1370 strcpy(after_user_id, after[U_USER_ID]);
984c91b7 1371
89db421e 1372 if ((beforec == 0) && (afterc == 0)) /*this case should never happen */
984c91b7 1373 return;
cd9e6b16 1374
89db421e 1375 if ((beforec == 0) && (afterc != 0)) /*this case only happens when the account*/
1376 return; /*account is first created but not usable*/
f75f605a 1377
89db421e 1378 if ((beforec != 0) && (afterc == 0)) /*this case only happens when the account*/
1379 { /*is expunged*/
1380 if (atoi(before[U_STATE]) == 0)
cd9e6b16 1381 {
89db421e 1382 com_err(whoami, 0, "expunging user %s from AD", before[U_NAME]);
1383 user_delete(ldap_handle, dn_path, before[U_NAME], before_user_id);
cd9e6b16 1384 }
f75f605a 1385 return;
5d0a7127 1386 }
f75f605a 1387
89db421e 1388 /*process anything that gets here*/
c0bd7667 1389 if ((rc = check_user(ldap_handle, dn_path, before[U_NAME],
1390 before_user_id)) == AD_NO_USER_FOUND)
5d0a7127 1391 {
6c8f12af 1392 if (!check_string(after[U_NAME]))
1393 return;
f75f605a 1394 if (rc = moira_connect())
1395 {
1396 critical_alert("AD incremental",
1397 "Error connection to Moira : %s",
1398 error_message(rc));
1399 return;
1400 }
89db421e 1401 com_err(whoami, 0, "creating user %s", after[U_NAME]);
5d0a7127 1402
984c91b7 1403 av[0] = after[U_NAME];
cd9e6b16 1404 call_args[0] = (char *)ldap_handle;
1405 call_args[1] = dn_path;
89db421e 1406 call_args[2] = after_user_id;
9db0b148 1407 call_args[3] = NULL;
cd9e6b16 1408 sid_base = NULL;
1409 sid_ptr = &sid_base;
5b8457c5 1410 callback_rc = 0;
cd9e6b16 1411 if (rc = mr_query("get_user_account_by_login", 1, av, user_create,
1412 call_args))
1413 {
f75f605a 1414 moira_disconnect();
89db421e 1415 com_err(whoami, 0, "couldn't create user %s : %s",
f75f605a 1416 after[U_NAME], error_message(rc));
1417 return;
cd9e6b16 1418 }
5b8457c5 1419 if (callback_rc)
1420 {
1421 moira_disconnect();
89db421e 1422 com_err(whoami, 0, "couldn't create user %s", after[U_NAME]);
5b8457c5 1423 return;
1424 }
f75f605a 1425 sleep(1);
cd9e6b16 1426 if (sid_base != NULL)
1427 {
1428 sid_update(ldap_handle, dn_path);
1429 linklist_free(sid_base);
1430 }
89db421e 1431 return;
1432 }
1433 else
1434 {
1435 if (rc != 0)
1436 return;
1437 }
1438 if (strcmp(before[U_NAME], after[U_NAME]))
1439 {
1440 if ((check_string(before[U_NAME])) && (check_string(after[U_NAME])))
f75f605a 1441 {
89db421e 1442 com_err(whoami, 0, "changing user %s to %s",
1443 before[U_NAME], after[U_NAME]);
1444 if ((rc = user_rename(ldap_handle, dn_path, before[U_NAME],
1445 after[U_NAME])) != LDAP_SUCCESS)
f75f605a 1446 {
89db421e 1447 return;
f75f605a 1448 }
1449 }
cd9e6b16 1450 }
89db421e 1451 com_err(whoami, 0, "updating user %s information", after[U_NAME]);
1452 rc = user_update(ldap_handle, dn_path, after[U_NAME],
1453 after[U_UID], after[U_MITID],
3abb4456 1454 after_user_id, atoi(after[U_STATE]),
1455 after[U_HOMEDIR], after[U_PROFILEDIR]);
f75f605a 1456 return;
5d0a7127 1457}
1458
1459int construct_newvalues(LK_ENTRY *linklist_base, int modvalue_count,
cd9e6b16 1460 char *oldValue, char *newValue,
1461 char ***modvalues, int type)
5d0a7127 1462{
cd9e6b16 1463 LK_ENTRY *linklist_ptr;
1464 int i;
1465 char *cPtr;
5d0a7127 1466
cd9e6b16 1467 if (((*modvalues) = calloc(1, (modvalue_count + 1) * sizeof(char *)))
1468 == NULL)
1469 {
1470 return(1);
1471 }
5d0a7127 1472 for (i = 0; i < (modvalue_count + 1); i++)
cd9e6b16 1473 (*modvalues)[i] = NULL;
5d0a7127 1474 if (modvalue_count != 0)
1475 {
1476 linklist_ptr = linklist_base;
1477 for (i = 0; i < modvalue_count; i++)
cd9e6b16 1478 {
1479 if ((oldValue != NULL) && (newValue != NULL))
1480 {
1481 if ((cPtr = (char *)strstr(linklist_ptr->value, oldValue))
1482 != (char *)NULL)
1483 {
1484 if (type == REPLACE)
1485 {
1486 if (((*modvalues)[i] = calloc(1, strlen(newValue) + 1))
1487 == NULL)
1488 return(1);
1489 memset((*modvalues)[i], '\0', strlen(newValue) + 1);
1490 strcpy((*modvalues)[i], newValue);
1491 }
1492 else
1493 {
1494 if (((*modvalues)[i] = calloc(1,
1495 (int)(cPtr - linklist_ptr->value) +
1496 (linklist_ptr->length - strlen(oldValue)) +
1497 strlen(newValue) + 1)) == NULL)
1498 return(1);
1499 memset((*modvalues)[i], '\0',
1500 (int)(cPtr - linklist_ptr->value) +
1501 (linklist_ptr->length - strlen(oldValue)) +
1502 strlen(newValue) + 1);
1503 memcpy((*modvalues)[i], linklist_ptr->value,
1504 (int)(cPtr - linklist_ptr->value));
1505 strcat((*modvalues)[i], newValue);
1506 strcat((*modvalues)[i],
1507 &linklist_ptr->value[(int)(cPtr - linklist_ptr->value) + strlen(oldValue)]);
1508 }
1509 }
1510 else
1511 {
1512 (*modvalues)[i] = calloc(1, linklist_ptr->length + 1);
1513 memset((*modvalues)[i], '\0', linklist_ptr->length + 1);
1514 memcpy((*modvalues)[i], linklist_ptr->value,
1515 linklist_ptr->length);
1516 }
1517 }
1518 else
1519 {
1520 (*modvalues)[i] = calloc(1, linklist_ptr->length + 1);
1521 memset((*modvalues)[i], '\0', linklist_ptr->length + 1);
1522 memcpy((*modvalues)[i], linklist_ptr->value,
1523 linklist_ptr->length);
1524 }
1525 linklist_ptr = linklist_ptr->next;
1526 }
1527 (*modvalues)[i] = NULL;
5d0a7127 1528 }
1529 return(0);
1530}
1531
cd9e6b16 1532
5d0a7127 1533int linklist_build(LDAP *ldap_handle, char *dn_path, char *search_exp,
cd9e6b16 1534 char **attr_array, LK_ENTRY **linklist_base,
1535 int *linklist_count)
5d0a7127 1536{
cd9e6b16 1537 ULONG rc;
5d0a7127 1538 LDAPMessage *ldap_entry;
cd9e6b16 1539
1540 rc = 0;
5d0a7127 1541 ldap_entry = NULL;
1542 (*linklist_base) = NULL;
1543 (*linklist_count) = 0;
1544 if ((rc = ldap_search_s(ldap_handle, dn_path, LDAP_SCOPE_SUBTREE,
cd9e6b16 1545 search_exp, attr_array, 0, &ldap_entry))
5d0a7127 1546 != LDAP_SUCCESS)
6c8f12af 1547 {
1548 if (rc != LDAP_SIZELIMIT_EXCEEDED)
1549 return(0);
1550 }
1551
cd9e6b16 1552 rc = retrieve_entries(ldap_handle, ldap_entry, linklist_base, linklist_count);
1553
5d0a7127 1554 ldap_msgfree(ldap_entry);
1555 return(rc);
1556}
1557
cd9e6b16 1558
5d0a7127 1559int retrieve_entries(LDAP *ldap_handle, LDAPMessage *ldap_entry,
cd9e6b16 1560 LK_ENTRY **linklist_base, int *linklist_count)
5d0a7127 1561{
cd9e6b16 1562 char distinguished_name[1024];
1563 LK_ENTRY *linklist_ptr;
1564 int rc;
1565
5d0a7127 1566 if ((ldap_entry = ldap_first_entry(ldap_handle, ldap_entry)) == NULL)
1567 return(0);
cd9e6b16 1568
1569 memset(distinguished_name, '\0', sizeof(distinguished_name));
1570 get_distinguished_name(ldap_handle, ldap_entry, distinguished_name);
1571
1572 if ((rc = retrieve_attributes(ldap_handle, ldap_entry, distinguished_name,
1573 linklist_base)) != 0)
5d0a7127 1574 return(rc);
cd9e6b16 1575
5d0a7127 1576 while ((ldap_entry = ldap_next_entry(ldap_handle, ldap_entry)) != NULL)
1577 {
cd9e6b16 1578 memset(distinguished_name, '\0', sizeof(distinguished_name));
1579 get_distinguished_name(ldap_handle, ldap_entry, distinguished_name);
1580
1581 if ((rc = retrieve_attributes(ldap_handle, ldap_entry, distinguished_name,
1582 linklist_base)) != 0)
1583 return(rc);
5d0a7127 1584 }
cd9e6b16 1585
5d0a7127 1586 linklist_ptr = (*linklist_base);
1587 (*linklist_count) = 0;
1588 while (linklist_ptr != NULL)
1589 {
1590 ++(*linklist_count);
1591 linklist_ptr = linklist_ptr->next;
1592 }
1593 return(0);
1594}
1595
1596int retrieve_attributes(LDAP *ldap_handle, LDAPMessage *ldap_entry,
cd9e6b16 1597 char *distinguished_name, LK_ENTRY **linklist_current)
5d0a7127 1598{
cd9e6b16 1599 char *Attribute;
1600 BerElement *ptr;
1601
5d0a7127 1602 ptr = NULL;
cd9e6b16 1603 if ((Attribute = ldap_first_attribute(ldap_handle, ldap_entry, &ptr)) != NULL)
5d0a7127 1604 {
cd9e6b16 1605 retrieve_values(ldap_handle, ldap_entry, Attribute, distinguished_name,
1606 linklist_current);
5d0a7127 1607 ldap_memfree(Attribute);
cd9e6b16 1608 while ((Attribute = ldap_next_attribute(ldap_handle, ldap_entry,
1609 ptr)) != NULL)
1610 {
1611 retrieve_values(ldap_handle, ldap_entry, Attribute,
1612 distinguished_name, linklist_current);
1613 ldap_memfree(Attribute);
1614 }
5d0a7127 1615 }
cd9e6b16 1616 ldap_ber_free(ptr, 0);
5d0a7127 1617 return(0);
1618}
1619
cd9e6b16 1620int retrieve_values(LDAP *ldap_handle, LDAPMessage *ldap_entry,
1621 char *Attribute, char *distinguished_name,
1622 LK_ENTRY **linklist_current)
5d0a7127 1623{
cd9e6b16 1624 char **str_value;
1625 char temp[256];
1626 void **Ptr;
1627 int use_bervalue;
1628 LK_ENTRY *linklist_previous;
5d0a7127 1629 LDAP_BERVAL **ber_value;
cd9e6b16 1630 DWORD ber_length;
5d0a7127 1631#ifdef LDAP_DEBUG
cd9e6b16 1632 SID *sid;
1633 GUID *guid;
1634 int i;
1635 int intValue;
1636 DWORD *subauth;
1637 SID_IDENTIFIER_AUTHORITY *sid_auth;
1638 unsigned char *subauth_count;
1639#endif /*LDAP_BEGUG*/
5d0a7127 1640
1641 use_bervalue = 0;
1642 memset(temp, '\0', sizeof(temp));
1643 if ((!strcmp(Attribute, "objectSid")) ||
1644 (!strcmp(Attribute, "objectGUID")))
1645 use_bervalue = 1;
cd9e6b16 1646
5d0a7127 1647 if (use_bervalue)
1648 {
1649 ber_value = ldap_get_values_len(ldap_handle, ldap_entry, Attribute);
1650 Ptr = (void **)ber_value;
1651 str_value = NULL;
cd9e6b16 1652 }
5d0a7127 1653 else
1654 {
1655 str_value = ldap_get_values(ldap_handle, ldap_entry, Attribute);
1656 Ptr = (void **)str_value;
1657 ber_value = NULL;
1658 }
1659 if (Ptr != NULL)
1660 {
1661 for (; *Ptr; Ptr++)
cd9e6b16 1662 {
1663 if ((linklist_previous = calloc(1, sizeof(LK_ENTRY))) == NULL)
1664 return(1);
1665 memset(linklist_previous, '\0', sizeof(LK_ENTRY));
1666 linklist_previous->next = (*linklist_current);
1667 (*linklist_current) = linklist_previous;
1668
1669 if (((*linklist_current)->attribute = calloc(1,
1670 strlen(Attribute) + 1)) == NULL)
1671 return(1);
1672 memset((*linklist_current)->attribute, '\0', strlen(Attribute) + 1);
1673 strcpy((*linklist_current)->attribute, Attribute);
1674 if (use_bervalue)
1675 {
1676 ber_length = (*(LDAP_BERVAL **)Ptr)->bv_len;
1677 if (((*linklist_current)->value = calloc(1, ber_length)) == NULL)
1678 return(1);
1679 memset((*linklist_current)->value, '\0', ber_length);
1680 memcpy((*linklist_current)->value, (*(LDAP_BERVAL **)Ptr)->bv_val,
1681 ber_length);
1682 (*linklist_current)->length = ber_length;
1683 }
1684 else
1685 {
1686 if (((*linklist_current)->value = calloc(1,
1687 strlen(*Ptr) + 1)) == NULL)
1688 return(1);
1689 memset((*linklist_current)->value, '\0', strlen(*Ptr) + 1);
1690 (*linklist_current)->length = strlen(*Ptr);
1691 strcpy((*linklist_current)->value, *Ptr);
1692 }
1693 (*linklist_current)->ber_value = use_bervalue;
1694 if (((*linklist_current)->dn = calloc(1,
1695 strlen(distinguished_name) + 1)) == NULL)
1696 return(1);
1697 memset((*linklist_current)->dn, '\0', strlen(distinguished_name) + 1);
1698 strcpy((*linklist_current)->dn, distinguished_name);
1699
5d0a7127 1700#ifdef LDAP_DEBUG
cd9e6b16 1701 if (!strcmp(Attribute, "objectGUID"))
1702 {
1703 guid = (GUID *)((*linklist_current)->value);
1704 sprintf(temp, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
1705 guid->Data1, guid->Data2, guid->Data3,
1706 guid->Data4[0], guid->Data4[1], guid->Data4[2],
1707 guid->Data4[3], guid->Data4[4], guid->Data4[5],
1708 guid->Data4[6], guid->Data4[7]);
1709 print_to_screen(" %20s : {%s}\n", Attribute, temp);
1710 }
1711 else if (!strcmp(Attribute, "objectSid"))
1712 {
1713 sid = (SID *)((*(LDAP_BERVAL **)Ptr)->bv_val);
5d0a7127 1714#ifdef _WIN32
cd9e6b16 1715 print_to_screen(" Revision = %d\n", sid->Revision);
1716 print_to_screen(" SID Identifier Authority:\n");
1717 sid_auth = &sid->IdentifierAuthority;
1718 if (sid_auth->Value[0])
1719 print_to_screen(" SECURITY_NULL_SID_AUTHORITY\n");
1720 else if (sid_auth->Value[1])
1721 print_to_screen(" SECURITY_WORLD_SID_AUTHORITY\n");
1722 else if (sid_auth->Value[2])
1723 print_to_screen(" SECURITY_LOCAL_SID_AUTHORITY\n");
1724 else if (sid_auth->Value[3])
1725 print_to_screen(" SECURITY_CREATOR_SID_AUTHORITY\n");
1726 else if (sid_auth->Value[5])
1727 print_to_screen(" SECURITY_NT_AUTHORITY\n");
1728 else
1729 print_to_screen(" UNKNOWN SID AUTHORITY\n");
1730 subauth_count = GetSidSubAuthorityCount(sid);
1731 print_to_screen(" SidSubAuthorityCount = %d\n",
1732 *subauth_count);
1733 print_to_screen(" SidSubAuthority:\n");
1734 for (i = 0; i < *subauth_count; i++)
1735 {
1736 if ((subauth = GetSidSubAuthority(sid, i)) != NULL)
1737 print_to_screen(" %u\n", *subauth);
1738 }
5d0a7127 1739#endif
cd9e6b16 1740 }
1741 else if ((!memcmp(Attribute, "userAccountControl",
1742 strlen("userAccountControl"))) ||
1743 (!memcmp(Attribute, "sAMAccountType",
1744 strlen("sAmAccountType"))))
1745 {
1746 intValue = atoi(*Ptr);
1747 print_to_screen(" %20s : %ld\n",Attribute, intValue);
1748 if (!memcmp(Attribute, "userAccountControl",
1749 strlen("userAccountControl")))
1750 {
1751 if (intValue & UF_ACCOUNTDISABLE)
1752 print_to_screen(" %20s : %s\n",
1753 "", "Account disabled");
1754 else
1755 print_to_screen(" %20s : %s\n",
1756 "", "Account active");
1757 if (intValue & UF_HOMEDIR_REQUIRED)
1758 print_to_screen(" %20s : %s\n",
1759 "", "Home directory required");
1760 if (intValue & UF_LOCKOUT)
1761 print_to_screen(" %20s : %s\n",
1762 "", "Account locked out");
1763 if (intValue & UF_PASSWD_NOTREQD)
1764 print_to_screen(" %20s : %s\n",
1765 "", "No password required");
1766 if (intValue & UF_PASSWD_CANT_CHANGE)
1767 print_to_screen(" %20s : %s\n",
1768 "", "Cannot change password");
1769 if (intValue & UF_TEMP_DUPLICATE_ACCOUNT)
1770 print_to_screen(" %20s : %s\n",
1771 "", "Temp duplicate account");
1772 if (intValue & UF_NORMAL_ACCOUNT)
1773 print_to_screen(" %20s : %s\n",
1774 "", "Normal account");
1775 if (intValue & UF_INTERDOMAIN_TRUST_ACCOUNT)
1776 print_to_screen(" %20s : %s\n",
1777 "", "Interdomain trust account");
1778 if (intValue & UF_WORKSTATION_TRUST_ACCOUNT)
1779 print_to_screen(" %20s : %s\n",
1780 "", "Workstation trust account");
1781 if (intValue & UF_SERVER_TRUST_ACCOUNT)
1782 print_to_screen(" %20s : %s\n",
1783 "", "Server trust account");
1784 }
1785 }
1786 else
1787 {
1788 print_to_screen(" %20s : %s\n",Attribute, *Ptr);
1789 }
5d0a7127 1790#endif /*LDAP_DEBUG*/
cd9e6b16 1791 }
5d0a7127 1792 if (str_value != NULL)
cd9e6b16 1793 ldap_value_free(str_value);
5d0a7127 1794 if (ber_value != NULL)
cd9e6b16 1795 ldap_value_free_len(ber_value);
5d0a7127 1796 }
1797 (*linklist_current) = linklist_previous;
1798 return(0);
1799}
1800
5d0a7127 1801int moira_connect(void)
1802{
cd9e6b16 1803 long rc;
1804 char HostName[64];
1805
5d0a7127 1806 if (!mr_connections++)
1807 {
1808#ifdef _WIN32
1809 memset(HostName, '\0', sizeof(HostName));
1810 strcpy(HostName, "ttsp");
cd9e6b16 1811 rc = mr_connect_cl(HostName, "winad.incr", QUERY_VERSION, 1);
1812/*det
5d0a7127 1813 rc = mr_connect(HostName);
cd9e6b16 1814*/
5d0a7127 1815#else
1816 struct utsname uts;
1817 uname(&uts);
cd9e6b16 1818 rc = mr_connect_cl(uts.nodename, "winad.incr", QUERY_VERSION, 1);
1819/*
5d0a7127 1820 rc = mr_connect(uts.nodename);
cd9e6b16 1821*/
5d0a7127 1822#endif /*WIN32*/
cd9e6b16 1823/*det
5d0a7127 1824 if (!rc)
cd9e6b16 1825 rc = mr_auth("winad.incr");
1826*/
5d0a7127 1827 return rc;
1828 }
1829 return 0;
1830}
1831
0d958b3c 1832void check_winad(void)
1833{
1834 int i;
1835
1836 for (i = 0; file_exists(STOP_FILE); i++)
1837 {
1838 if (i > 30)
1839 {
f75f605a 1840 critical_alert("AD incremental",
f78c7eaf 1841 "WINAD incremental failed (%s exists): %s",
1842 STOP_FILE, tbl_buf);
1843 exit(1);
1844 }
0d958b3c 1845 sleep(60);
1846 }
1847}
1848
5d0a7127 1849int moira_disconnect(void)
1850{
5d0a7127 1851
cd9e6b16 1852 if (!--mr_connections)
5d0a7127 1853 {
cd9e6b16 1854 mr_disconnect();
5d0a7127 1855 }
cd9e6b16 1856 return 0;
5d0a7127 1857}
1858
5d0a7127 1859void get_distinguished_name(LDAP *ldap_handle, LDAPMessage *ldap_entry,
cd9e6b16 1860 char *distinguished_name)
5d0a7127 1861{
cd9e6b16 1862 char *CName;
1863
5d0a7127 1864 CName = ldap_get_dn(ldap_handle, ldap_entry);
1865 if (CName == NULL)
1866 return;
1867 strcpy(distinguished_name, CName);
1868 ldap_memfree(CName);
1869}
1870
1871int linklist_create_entry(char *attribute, char *value,
cd9e6b16 1872 LK_ENTRY **linklist_entry)
5d0a7127 1873{
1874 (*linklist_entry) = calloc(1, sizeof(LK_ENTRY));
1875 if (!(*linklist_entry))
1876 {
1877 return(1);
1878 }
1879 memset((*linklist_entry), '\0', sizeof(LK_ENTRY));
1880 (*linklist_entry)->attribute = calloc(1, strlen(attribute) + 1);
1881 memset((*linklist_entry)->attribute, '\0', strlen(attribute) + 1);
1882 strcpy((*linklist_entry)->attribute, attribute);
1883 (*linklist_entry)->value = calloc(1, strlen(value) + 1);
1884 memset((*linklist_entry)->value, '\0', strlen(value) + 1);
1885 strcpy((*linklist_entry)->value, value);
1886 (*linklist_entry)->length = strlen(value);
1887 (*linklist_entry)->next = NULL;
1888 return(0);
1889}
1890
1891void print_to_screen(const char *fmt, ...)
1892{
1893 va_list pvar;
cd9e6b16 1894
5d0a7127 1895 va_start(pvar, fmt);
1896 vfprintf(stderr, fmt, pvar);
1897 fflush(stderr);
1898 va_end(pvar);
1899}
cd9e6b16 1900
1901int get_group_membership(char *group_membership, char *group_ou,
1902 int *security_flag, char **av)
1903{
1904 int maillist_flag;
1905 int group_flag;
1906
1907 maillist_flag = atoi(av[L_MAILLIST]);
1908 group_flag = atoi(av[L_GROUP]);
1909 if (security_flag != NULL)
1910 (*security_flag) = 0;
1911
1912 if ((maillist_flag) && (group_flag))
1913 {
1914 if (group_membership != NULL)
1915 group_membership[0] = 'B';
1916 if (security_flag != NULL)
1917 (*security_flag) = 1;
1918 if (group_ou != NULL)
1919 strcpy(group_ou, group_ou_both);
1920 }
1921 else if ((!maillist_flag) && (group_flag))
1922 {
1923 if (group_membership != NULL)
1924 group_membership[0] = 'S';
1925 if (security_flag != NULL)
1926 (*security_flag) = 1;
1927 if (group_ou != NULL)
1928 strcpy(group_ou, group_ou_security);
1929 }
1930 else if ((maillist_flag) && (!group_flag))
1931 {
1932 if (group_membership != NULL)
1933 group_membership[0] = 'D';
1934 if (group_ou != NULL)
1935 strcpy(group_ou, group_ou_distribution);
1936 }
1937 else
1938 {
1939 if (group_membership != NULL)
1940 group_membership[0] = 'N';
1941 if (group_ou != NULL)
1942 strcpy(group_ou, group_ou_neither);
1943 }
1944 return(0);
1945}
1946
f75f605a 1947int group_rename(LDAP *ldap_handle, char *dn_path,
1948 char *before_group_name, char *before_group_membership,
5a775f54 1949 char *before_group_ou, int before_security_flag, char *before_desc,
f75f605a 1950 char *after_group_name, char *after_group_membership,
89db421e 1951 char *after_group_ou, int after_security_flag, char *after_desc,
1952 char *MoiraId, char *filter)
9db0b148 1953{
1954 LDAPMod *mods[20];
1955 char old_dn[512];
1956 char new_dn[512];
78af4e6e 1957 char new_dn_path[512];
78af4e6e 1958 char sam_name[256];
9db0b148 1959 char *attr_array[3];
89db421e 1960 char *mitMoiraId_v[] = {NULL, NULL};
9db0b148 1961 char *name_v[] = {NULL, NULL};
5a775f54 1962 char *desc_v[] = {NULL, NULL};
78af4e6e 1963 char *samAccountName_v[] = {NULL, NULL};
c76c595a 1964 char *groupTypeControl_v[] = {NULL, NULL};
1965 u_int groupTypeControl = ADS_GROUP_TYPE_GLOBAL_GROUP;
1966 char groupTypeControlStr[80];
9db0b148 1967 int n;
1968 int i;
1969 int rc;
9db0b148 1970 LK_ENTRY *group_base;
1971 int group_count;
9db0b148 1972
f75f605a 1973 if (!check_string(before_group_name))
78af4e6e 1974 {
f75f605a 1975 com_err(whoami, 0, "invalid LDAP list name %s", before_group_name);
89db421e 1976 return(AD_INVALID_NAME);
78af4e6e 1977 }
f75f605a 1978 if (!check_string(after_group_name))
78af4e6e 1979 {
f75f605a 1980 com_err(whoami, 0, "invalid LDAP list name %s", after_group_name);
89db421e 1981 return(AD_INVALID_NAME);
1982 }
1983
1984 group_count = 0;
1985 group_base = NULL;
1986 if (rc = ad_get_group(ldap_handle, dn_path, before_group_name,
1987 before_group_membership,
1988 MoiraId, "distinguishedName", &group_base,
1989 &group_count, filter))
1990 return(rc);
1991
1992 if (group_count == 0)
1993 {
1994 return(AD_NO_GROUPS_FOUND);
1995 }
1996 if (group_count != 1)
1997 {
1998 com_err(whoami, 0,
1999 "multiple groups with MoiraId = %s exist in the AD",
2000 MoiraId);
2001 return(AD_MULTIPLE_GROUPS_FOUND);
78af4e6e 2002 }
89db421e 2003 strcpy(old_dn, group_base->value);
78af4e6e 2004
89db421e 2005 linklist_free(group_base);
2006 group_base = NULL;
2007 group_count = 0;
2008 attr_array[0] = "sAMAccountName";
9db0b148 2009 attr_array[1] = NULL;
89db421e 2010 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
9db0b148 2011 &group_base, &group_count)) != 0)
2012 {
f75f605a 2013 com_err(whoami, 0, "LDAP server unable to get list %s dn : %s",
2014 after_group_name, ldap_err2string(rc));
2015 return(rc);
9db0b148 2016 }
2017 if (group_count != 1)
2018 {
89db421e 2019 com_err(whoami, 0,
2020 "Unable to get sAMAccountName for group %s",
2021 before_group_name);
2022 return(AD_LDAP_FAILURE);
9db0b148 2023 }
89db421e 2024
2025 strcpy(sam_name, group_base->value);
9db0b148 2026 linklist_free(group_base);
2027 group_base = NULL;
2028 group_count = 0;
2029
f75f605a 2030 sprintf(new_dn_path, "%s,%s", after_group_ou, dn_path);
2031 sprintf(new_dn, "cn=%s", after_group_name);
2032 if ((rc = ldap_rename_s(ldap_handle, old_dn, new_dn, new_dn_path,
78af4e6e 2033 TRUE, NULL, NULL)) != LDAP_SUCCESS)
2034 {
f75f605a 2035 com_err(whoami, 0, "Couldn't rename list from %s to %s : %s",
89db421e 2036 before_group_name, after_group_name, ldap_err2string(rc));
f75f605a 2037 return(rc);
78af4e6e 2038 }
9db0b148 2039
f75f605a 2040 name_v[0] = after_group_name;
c0bd7667 2041 if (!strncmp(&sam_name[strlen(sam_name) - strlen("_group")], "_group", strlen("_group")))
89db421e 2042 {
2043 sprintf(sam_name, "%s_group", after_group_name);
2044 }
2045 else
2046 {
2047 com_err(whoami, 0, "Couldn't rename list from %s to %s : sAMAccountName not found",
2048 before_group_name, after_group_name);
2049 return(rc);
2050 }
78af4e6e 2051 samAccountName_v[0] = sam_name;
c76c595a 2052 if (after_security_flag)
2053 groupTypeControl |= ADS_GROUP_TYPE_SECURITY_ENABLED;
2054 sprintf(groupTypeControlStr, "%ld", groupTypeControl);
2055 groupTypeControl_v[0] = groupTypeControlStr;
9db0b148 2056 n = 0;
5a775f54 2057 ADD_ATTR("samAccountName", samAccountName_v, LDAP_MOD_REPLACE);
9db0b148 2058 ADD_ATTR("displayName", name_v, LDAP_MOD_REPLACE);
89db421e 2059 desc_v[0] = after_desc;
5a775f54 2060 if (strlen(after_desc) == 0)
2061 desc_v[0] = NULL;
2062 ADD_ATTR("description", desc_v, LDAP_MOD_REPLACE);
89db421e 2063 mitMoiraId_v[0] = MoiraId;
2064 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_REPLACE);
c76c595a 2065 ADD_ATTR("groupType", groupTypeControl_v, LDAP_MOD_REPLACE);
9db0b148 2066 mods[n] = NULL;
f75f605a 2067 sprintf(new_dn, "cn=%s,%s,%s", after_group_name, after_group_ou, dn_path);
2068 if ((rc = ldap_modify_s(ldap_handle, new_dn, mods)) != LDAP_SUCCESS)
78af4e6e 2069 {
f75f605a 2070 com_err(whoami, 0, "After renaming, couldn't modify list data for %s : %s",
2071 after_group_name, ldap_err2string(rc));
78af4e6e 2072 }
9db0b148 2073 for (i = 0; i < n; i++)
2074 free(mods[i]);
f75f605a 2075 return(rc);
9db0b148 2076}
2077
cd9e6b16 2078int group_create(int ac, char **av, void *ptr)
2079{
2080 LDAPMod *mods[20];
5b8457c5 2081 LK_ENTRY *group_base;
cd9e6b16 2082 char new_dn[256];
2083 char group_ou[256];
2084 char new_group_name[256];
2085 char sam_group_name[256];
2086 char cn_group_name[256];
2087 char *cn_v[] = {NULL, NULL};
2088 char *objectClass_v[] = {"top", "group", NULL};
2089 char info[256];
2090 char *samAccountName_v[] = {NULL, NULL};
cd9e6b16 2091 char *altSecurityIdentities_v[] = {NULL, NULL};
89db421e 2092 char *member_v[] = {NULL, NULL};
cd9e6b16 2093 char *name_v[] = {NULL, NULL};
2094 char *desc_v[] = {NULL, NULL};
2095 char *info_v[] = {NULL, NULL};
89db421e 2096 char *mitMoiraId_v[] = {NULL, NULL};
cd9e6b16 2097 char *groupTypeControl_v[] = {NULL, NULL};
2098 char groupTypeControlStr[80];
2099 char group_membership[1];
2100 int i;
2101 int security_flag;
2102 u_int groupTypeControl = ADS_GROUP_TYPE_GLOBAL_GROUP;
2103 int n;
2104 int rc;
5b8457c5 2105 int group_count;
89db421e 2106 int updateGroup;
2107 char filter[128];
cd9e6b16 2108 char *attr_array[3];
2109 char **call_args;
2110
2111 call_args = ptr;
2112
cd9e6b16 2113 if (!check_string(av[L_NAME]))
78af4e6e 2114 {
f75f605a 2115 com_err(whoami, 0, "invalid LDAP list name %s", av[L_NAME]);
89db421e 2116 return(AD_INVALID_NAME);
78af4e6e 2117 }
f75f605a 2118
89db421e 2119 updateGroup = (int)call_args[4];
cd9e6b16 2120 memset(group_ou, 0, sizeof(group_ou));
2121 memset(group_membership, 0, sizeof(group_membership));
2122 security_flag = 0;
2123 get_group_membership(group_membership, group_ou, &security_flag, av);
89db421e 2124 strcpy(new_group_name, av[L_NAME]);
2125 sprintf(new_dn, "cn=%s,%s,%s", new_group_name, group_ou, call_args[1]);
cd9e6b16 2126 if (security_flag)
2127 groupTypeControl |= ADS_GROUP_TYPE_SECURITY_ENABLED;
89db421e 2128
2129 sprintf(sam_group_name, "%s_group", av[L_NAME]);
cd9e6b16 2130
89db421e 2131 if (!updateGroup)
2132 {
cd9e6b16 2133
89db421e 2134 sprintf(groupTypeControlStr, "%ld", groupTypeControl);
2135 groupTypeControl_v[0] = groupTypeControlStr;
cd9e6b16 2136
89db421e 2137 strcpy(cn_group_name, av[L_NAME]);
cd9e6b16 2138
89db421e 2139 samAccountName_v[0] = sam_group_name;
2140 name_v[0] = new_group_name;
2141 cn_v[0] = new_group_name;
cd9e6b16 2142
89db421e 2143 n = 0;
2144 ADD_ATTR("cn", cn_v, LDAP_MOD_ADD);
2145 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
2146 ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_ADD);
2147 ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
2148 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
2149 if (strlen(av[L_DESC]) != 0)
2150 {
2151 desc_v[0] = av[L_DESC];
2152 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
2153 }
2154 ADD_ATTR("groupType", groupTypeControl_v, LDAP_MOD_ADD);
2155 if (strlen(av[L_ACE_NAME]) != 0)
2156 {
2157 sprintf(info, "The Administrator of this list is: %s", av[L_ACE_NAME]);
2158 info_v[0] = info;
2159 ADD_ATTR("info", info_v, LDAP_MOD_ADD);
2160 }
2161 if (strlen(call_args[5]) != 0)
2162 {
2163 mitMoiraId_v[0] = call_args[5];
2164 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_ADD);
2165 }
2166 mods[n] = NULL;
2167
2168 rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL);
2169
2170 for (i = 0; i < n; i++)
2171 free(mods[i]);
2172 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
2173 {
909e0dc3 2174 com_err(whoami, 0, "Unable to create list %s in AD : %s",
89db421e 2175 av[L_NAME], ldap_err2string(rc));
2176 callback_rc = rc;
2177 return(rc);
2178 }
78af4e6e 2179 }
89db421e 2180 if ((rc == LDAP_ALREADY_EXISTS) || (updateGroup))
5a775f54 2181 {
2182 n = 0;
89db421e 2183 desc_v[0] = NULL;
2184 if (strlen(av[L_DESC]) != 0)
2185 desc_v[0] = av[L_DESC];
5a775f54 2186 ADD_ATTR("description", desc_v, LDAP_MOD_REPLACE);
89db421e 2187 info_v[0] = NULL;
2188 if (strlen(av[L_ACE_NAME]) != 0)
2189 {
2190 sprintf(info, "The Administrator of this list is: %s", av[L_ACE_NAME]);
2191 info_v[0] = info;
2192 }
2193 ADD_ATTR("info", info_v, LDAP_MOD_REPLACE);
2194 if (strlen(call_args[5]) != 0)
2195 {
2196 mitMoiraId_v[0] = call_args[5];
2197 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_REPLACE);
2198 }
2199 if (!(atoi(av[L_ACTIVE])))
2200 {
2201 member_v[0] = NULL;
2202 ADD_ATTR("member", member_v, LDAP_MOD_REPLACE);
2203 }
5a775f54 2204 mods[n] = NULL;
2205 rc = ldap_modify_s((LDAP *)call_args[0], new_dn, mods);
2206 for (i = 0; i < n; i++)
2207 free(mods[i]);
909e0dc3 2208 if (rc != LDAP_SUCCESS)
2209 {
2210 com_err(whoami, 0, "Unable to update list %s in AD : %s",
2211 av[L_NAME], ldap_err2string(rc));
2212 callback_rc = rc;
2213 return(rc);
2214 }
5a775f54 2215 }
89db421e 2216
909e0dc3 2217 ProcessGroupSecurity((LDAP *)call_args[0], call_args[1], av[L_NAME],
2218 atoi(av[L_HIDDEN]), av[L_ACE_TYPE], av[L_ACE_NAME]);
2219
89db421e 2220 sprintf(filter, "(sAMAccountName=%s)", sam_group_name);
2221 if (strlen(call_args[5]) != 0)
6c8f12af 2222 sprintf(filter, "(&(objectClass=group)(mitMoiraId=%s))", call_args[5]);
cd9e6b16 2223 attr_array[0] = "objectSid";
2224 attr_array[1] = NULL;
5b8457c5 2225 group_count = 0;
2226 group_base = NULL;
89db421e 2227 if ((rc = linklist_build((LDAP *)call_args[0], call_args[1], filter, attr_array,
5b8457c5 2228 &group_base, &group_count)) == LDAP_SUCCESS)
cd9e6b16 2229 {
3e586ecf 2230 if (group_count != 1)
2231 {
2232 if (strlen(call_args[5]) != 0)
2233 {
2234 linklist_free(group_base);
2235 group_count = 0;
2236 group_base = NULL;
2237 sprintf(filter, "(sAMAccountName=%s)", sam_group_name);
2238 rc = linklist_build((LDAP *)call_args[0], call_args[1], filter,
2239 attr_array, &group_base, &group_count);
2240 }
2241 }
5b8457c5 2242 if (group_count == 1)
cd9e6b16 2243 {
5b8457c5 2244 (*sid_ptr) = group_base;
cd9e6b16 2245 (*sid_ptr)->member = strdup(av[L_NAME]);
2246 (*sid_ptr)->type = (char *)GROUPS;
2247 sid_ptr = &(*sid_ptr)->next;
2248 }
5b8457c5 2249 else
2250 {
2251 if (group_base != NULL)
2252 linklist_free(group_base);
2253 }
cd9e6b16 2254 }
5b8457c5 2255 else
2256 {
2257 if (group_base != NULL)
2258 linklist_free(group_base);
2259 }
2260 return(LDAP_SUCCESS);
cd9e6b16 2261}
2262
909e0dc3 2263int ProcessGroupSecurity(LDAP *ldap_handle, char *dn_path, char *TargetGroupName,
2264 int HiddenGroup, char *AceType, char *AceName)
2265{
2266 char filter_exp[1024];
2267 char *attr_array[5];
2268 char search_path[512];
2269 char root_ou[128];
2270 char TemplateDn[512];
2271 char TemplateSamName[128];
2272 char TargetDn[512];
2273 char TargetSamName[128];
2274 char AceSamAccountName[128];
2275 char AceDn[256];
2276 unsigned char AceSid[128];
2277 unsigned char UserTemplateSid[128];
2278 char acBERBuf[N_SD_BER_BYTES];
2279 char GroupSecurityTemplate[256];
2280 int AceSidCount;
2281 int UserTemplateSidCount;
2282 int group_count;
2283 int n;
2284 int i;
2285 int rc;
2286 int nVal;
2287 ULONG dwInfo;
2288 int array_count = 0;
2289 LDAPMod *mods[20];
2290 LK_ENTRY *group_base;
2291 LDAP_BERVAL **ppsValues;
2292 LDAPControl sControl = {"1.2.840.113556.1.4.801",
2293 { N_SD_BER_BYTES, acBERBuf },
2294 TRUE
2295 };
2296 LDAPControl *apsServerControls[] = {&sControl, NULL};
2297 LDAPMessage *psMsg;
2298
2299 dwInfo = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION;
2300 BEREncodeSecurityBits(dwInfo, acBERBuf);
2301
2302 sprintf(search_path, "%s,%s", group_ou_root, dn_path);
2303 sprintf(filter_exp, "(sAMAccountName=%s_group)", TargetGroupName);
2304 attr_array[0] = "sAMAccountName";
2305 attr_array[1] = NULL;
2306 group_count = 0;
2307 group_base = NULL;
2308 if ((rc = linklist_build(ldap_handle, search_path, filter_exp, attr_array,
2309 &group_base, &group_count) != 0))
2310 return(1);
2311 if (group_count != 1)
2312 {
2313 linklist_free(group_base);
2314 return(1);
2315 }
2316 strcpy(TargetDn, group_base->dn);
2317 strcpy(TargetSamName, group_base->value);
2318 linklist_free(group_base);
2319 group_base = NULL;
2320 group_count = 0;
2321
2322 UserTemplateSidCount = 0;
2323 memset(UserTemplateSid, '\0', sizeof(UserTemplateSid));
2324 memset(AceSamAccountName, '\0', sizeof(AceSamAccountName));
2325 memset(AceSid, '\0', sizeof(AceSid));
2326 AceSidCount = 0;
2327 group_base = NULL;
2328 group_count = 0;
2329 if (strlen(AceName) != 0)
2330 {
2331 if (!strcmp(AceType, "LIST"))
2332 {
2333 sprintf(AceSamAccountName, "%s_group", AceName);
2334 strcpy(root_ou, group_ou_root);
2335 }
2336 else if (!strcmp(AceType, "USER"))
2337 {
2338 sprintf(AceSamAccountName, "%s", AceName);
2339 strcpy(root_ou, user_ou);
2340 }
2341 if (strlen(AceSamAccountName) != 0)
2342 {
bbef4f93 2343 sprintf(search_path, "%s", dn_path);
909e0dc3 2344 sprintf(filter_exp, "(sAMAccountName=%s)", AceSamAccountName);
2345 attr_array[0] = "objectSid";
2346 attr_array[1] = NULL;
2347 group_count = 0;
2348 group_base = NULL;
2349 if ((rc = linklist_build(ldap_handle, search_path, filter_exp, attr_array,
2350 &group_base, &group_count) != 0))
2351 return(1);
2352 if (group_count == 1)
2353 {
2354 strcpy(AceDn, group_base->dn);
2355 AceSidCount = group_base->length;
2356 memcpy(AceSid, group_base->value, AceSidCount);
2357 }
2358 linklist_free(group_base);
2359 group_base = NULL;
2360 group_count = 0;
2361 }
2362 }
2363 if (AceSidCount == 0)
2364 {
2365 com_err(whoami, 0, "Group %s: Administrator: %s, Type: %s - does not have an AD SID.", TargetGroupName, AceName, AceType);
2366 com_err(whoami, 0, " Non-admin security group template will be used.");
2367 }
2368 else
2369 {
2370 sprintf(search_path, "%s,%s", security_template_ou, dn_path);
2371 sprintf(filter_exp, "(sAMAccountName=%s)", "UserTemplate.u");
2372 attr_array[0] = "objectSid";
2373 attr_array[1] = NULL;
2374
2375 group_count = 0;
2376 group_base = NULL;
2377 if ((rc = linklist_build(ldap_handle, search_path, filter_exp, attr_array,
2378 &group_base, &group_count) != 0))
2379 return(1);
2380 if ((rc != 0) || (group_count != 1))
2381 {
2382 com_err(whoami, 0, "Couldn't process user security template: %s", "UserTemplate");
2383 AceSidCount = 0;
2384 }
2385 else
2386 {
2387 UserTemplateSidCount = group_base->length;
2388 memcpy(UserTemplateSid, group_base->value, UserTemplateSidCount);
2389 }
2390 linklist_free(group_base);
2391 group_base = NULL;
2392 group_count = 0;
2393 }
2394
2395 if (HiddenGroup)
2396 {
2397 if (AceSidCount == 0)
2398 {
2399 strcpy(GroupSecurityTemplate, HIDDEN_GROUP);
2400 sprintf(filter_exp, "(sAMAccountName=%s)", HIDDEN_GROUP);
2401 }
2402 else
2403 {
2404 strcpy(GroupSecurityTemplate, HIDDEN_GROUP_WITH_ADMIN);
2405 sprintf(filter_exp, "(sAMAccountName=%s)", HIDDEN_GROUP_WITH_ADMIN);
2406 }
2407 }
2408 else
2409 {
2410 if (AceSidCount == 0)
2411 {
2412 strcpy(GroupSecurityTemplate, NOT_HIDDEN_GROUP);
2413 sprintf(filter_exp, "(sAMAccountName=%s)", NOT_HIDDEN_GROUP);
2414 }
2415 else
2416 {
2417 strcpy(GroupSecurityTemplate, NOT_HIDDEN_GROUP_WITH_ADMIN);
2418 sprintf(filter_exp, "(sAMAccountName=%s)", NOT_HIDDEN_GROUP_WITH_ADMIN);
2419 }
2420 }
2421
2422 sprintf(search_path, "%s,%s", security_template_ou, dn_path);
2423 attr_array[0] = "sAMAccountName";
2424 attr_array[1] = NULL;
2425 group_count = 0;
2426 group_base = NULL;
2427 if ((rc = linklist_build(ldap_handle, search_path, filter_exp, attr_array,
2428 &group_base, &group_count) != 0))
2429 return(1);
2430 if (group_count != 1)
2431 {
2432 linklist_free(group_base);
2433 com_err(whoami, 0, "Couldn't process group security template: %s - security not set", GroupSecurityTemplate);
2434 return(1);
2435 }
2436 strcpy(TemplateDn, group_base->dn);
2437 strcpy(TemplateSamName, group_base->value);
2438 linklist_free(group_base);
2439 group_base = NULL;
2440 group_count = 0;
2441
2442 sprintf(filter_exp, "(sAMAccountName=%s)", TemplateSamName);
2443 rc = ldap_search_ext_s(ldap_handle,
2444 TemplateDn,
2445 LDAP_SCOPE_SUBTREE,
2446 filter_exp,
2447 NULL,
2448 0,
2449 apsServerControls,
2450 NULL,
2451 NULL,
2452 0,
2453 &psMsg);
2454
2455 if ((psMsg = ldap_first_entry(ldap_handle, psMsg)) == NULL)
2456 {
2457 com_err(whoami, 0, "Couldn't find group security template: %s - security not set", GroupSecurityTemplate);
2458 return(1);
2459 }
2460 ppsValues = ldap_get_values_len(ldap_handle, psMsg, "ntSecurityDescriptor");
2461 if (ppsValues == NULL)
2462 {
2463 com_err(whoami, 0, "Couldn't find group security descriptor for group %s - security not set", GroupSecurityTemplate);
2464 return(1);
2465 }
2466
2467 if (AceSidCount != 0)
2468 {
2469 for (nVal = 0; ppsValues[nVal] != NULL; nVal++)
2470 {
2471 for (i = 0; i < (int)(ppsValues[nVal]->bv_len - UserTemplateSidCount); i++)
2472 {
2473 if (!memcmp(&ppsValues[nVal]->bv_val[i], UserTemplateSid, UserTemplateSidCount))
2474 {
2475 memcpy(&ppsValues[nVal]->bv_val[i], AceSid, AceSidCount);
2476 break;
2477 }
2478 }
2479 }
2480 }
2481
2482 n = 0;
2483 ADD_ATTR("ntSecurityDescriptor", (char **)ppsValues, LDAP_MOD_REPLACE | LDAP_MOD_BVALUES);
2484 mods[n] = NULL;
2485
2486 rc = ldap_modify_s(ldap_handle, TargetDn, mods);
2487 for (i = 0; i < n; i++)
2488 free(mods[i]);
2489 ldap_value_free_len(ppsValues);
2490 ldap_msgfree(psMsg);
2491 if (rc != LDAP_SUCCESS)
2492 {
2493 com_err(whoami, 0, "Couldn't set security settings for group %s : %s",
2494 TargetGroupName, ldap_err2string(rc));
2495 if (AceSidCount != 0)
2496 {
2497 com_err(whoami, 0, "Trying to set security for group %s without admin.",
2498 TargetGroupName);
2499 if (rc = ProcessGroupSecurity(ldap_handle, dn_path, TargetGroupName,
2500 HiddenGroup, "", ""))
2501 {
2502 com_err(whoami, 0, "Unable to set security for group %s.",
2503 TargetGroupName);
2504 return(rc);
2505 }
2506 }
2507 return(rc);
2508 }
2509 com_err(whoami, 0, "Security set for group %s.", TargetGroupName);
2510 return(rc);
2511}
2512
89db421e 2513int group_delete(LDAP *ldap_handle, char *dn_path, char *group_name,
2514 char *group_membership, char *MoiraId)
cd9e6b16 2515{
2516 LK_ENTRY *group_base;
f75f605a 2517 char temp[512];
89db421e 2518 char filter[128];
cd9e6b16 2519 int group_count;
2520 int rc;
2521
f75f605a 2522 if (!check_string(group_name))
78af4e6e 2523 {
f75f605a 2524 com_err(whoami, 0, "invalid LDAP list name %s", group_name);
89db421e 2525 return(AD_INVALID_NAME);
78af4e6e 2526 }
89db421e 2527
2528 memset(filter, '\0', sizeof(filter));
cd9e6b16 2529 group_count = 0;
2530 group_base = NULL;
cd9e6b16 2531 sprintf(temp, "%s,%s", group_ou_root, dn_path);
89db421e 2532 if (rc = ad_get_group(ldap_handle, temp, group_name,
2533 group_membership, MoiraId,
2534 "distinguishedName", &group_base,
2535 &group_count, filter))
2536 return(rc);
2537
cd9e6b16 2538 if (group_count == 1)
78af4e6e 2539 {
2540 if ((rc = ldap_delete_s(ldap_handle, group_base->value)) != LDAP_SUCCESS)
2541 {
f75f605a 2542 linklist_free(group_base);
2543 com_err(whoami, 0, "Unable to delete list %s from AD : %s",
2544 group_name, ldap_err2string(rc));
89db421e 2545 return(rc);
78af4e6e 2546 }
f75f605a 2547 linklist_free(group_base);
78af4e6e 2548 }
2549 else
2550 {
f75f605a 2551 linklist_free(group_base);
2552 com_err(whoami, 0, "Unable to find list %s in AD.", group_name);
89db421e 2553 return(AD_NO_GROUPS_FOUND);
78af4e6e 2554 }
f75f605a 2555
78af4e6e 2556 return(0);
cd9e6b16 2557}
2558
909e0dc3 2559int BEREncodeSecurityBits(ULONG uBits, char *pBuffer)
2560{
2561 *pBuffer++ = 0x30;
2562 *pBuffer++ = 0x03;
2563 *pBuffer++ = 0x02;
2564 *pBuffer++ = 0x00;
2565 return(N_SD_BER_BYTES);
2566}
2567
f75f605a 2568int process_lists(int ac, char **av, void *ptr)
cd9e6b16 2569{
f75f605a 2570 int rc;
2571 int security_flag;
2572 char group_ou[256];
2573 char group_membership[2];
2574 char **call_args;
cd9e6b16 2575
2576 call_args = ptr;
2577
f75f605a 2578 security_flag = 0;
2579 memset(group_ou, '\0', sizeof(group_ou));
2580 memset(group_membership, '\0', sizeof(group_membership));
2581 get_group_membership(group_membership, group_ou, &security_flag, av);
2582 rc = member_add((LDAP *)call_args[0], (char *)call_args[1], av[L_NAME],
89db421e 2583 group_ou, group_membership, call_args[2],
2584 (char *)call_args[3], "");
cd9e6b16 2585 return(0);
2586}
2587
2588int member_list_build(int ac, char **av, void *ptr)
2589{
2590 LK_ENTRY *linklist;
78af4e6e 2591 char temp[1024];
cd9e6b16 2592 char **call_args;
2593
2594 call_args = ptr;
2595
2596 strcpy(temp, av[ACE_NAME]);
2597 if (!check_string(temp))
2598 return(0);
f78c7eaf 2599 if (!strcmp(av[ACE_TYPE], "USER"))
cd9e6b16 2600 {
f75f605a 2601 if (!((int)call_args[3] & MOIRA_USERS))
f78c7eaf 2602 return(0);
2603 }
2604 else if (!strcmp(av[ACE_TYPE], "STRING"))
2605 {
f75f605a 2606 if (!((int)call_args[3] & MOIRA_STRINGS))
f78c7eaf 2607 return(0);
2608 if (contact_create((LDAP *)call_args[0], call_args[1], temp, contact_ou))
2609 return(0);
cd9e6b16 2610 }
2611 else if (!strcmp(av[ACE_TYPE], "LIST"))
2612 {
f75f605a 2613 if (!((int)call_args[3] & MOIRA_LISTS))
f78c7eaf 2614 return(0);
cd9e6b16 2615 }
f78c7eaf 2616 else if (!strcmp(av[ACE_TYPE], "KERBEROS"))
cd9e6b16 2617 {
f75f605a 2618 if (!((int)call_args[3] & MOIRA_KERBEROS))
f78c7eaf 2619 return(0);
2620 if (contact_create((LDAP *)call_args[0], call_args[1], temp, kerberos_ou))
2621 return(0);
cd9e6b16 2622 }
f78c7eaf 2623 else
2624 return(0);
2625
cd9e6b16 2626 linklist = member_base;
2627 while (linklist)
2628 {
2629 if (!strcasecmp(temp, linklist->member))
2630 return(0);
2631 linklist = linklist->next;
2632 }
2633 linklist = calloc(1, sizeof(LK_ENTRY));
2634 linklist->op = 1;
2635 linklist->dn = NULL;
2636 linklist->list = calloc(1, strlen(call_args[2]) + 1);
2637 strcpy(linklist->list, call_args[2]);
2638 linklist->type = calloc(1, strlen(av[ACE_TYPE]) + 1);
2639 strcpy(linklist->type, av[ACE_TYPE]);
2640 linklist->member = calloc(1, strlen(temp) + 1);
2641 strcpy(linklist->member, temp);
2642 linklist->next = member_base;
2643 member_base = linklist;
2644 return(0);
2645}
2646
78af4e6e 2647int member_remove(LDAP *ldap_handle, char *dn_path, char *group_name,
f75f605a 2648 char *group_ou, char *group_membership, char *user_name,
89db421e 2649 char *UserOu, char *MoiraId)
78af4e6e 2650{
2651 char distinguished_name[1024];
f75f605a 2652 char *modvalues[2];
78af4e6e 2653 char temp[256];
89db421e 2654 char filter[128];
78af4e6e 2655 int group_count;
2656 int i;
2657 int n;
2658 LDAPMod *mods[20];
2659 LK_ENTRY *group_base;
2660 ULONG rc;
2661
2662 if (!check_string(group_name))
89db421e 2663 return(AD_INVALID_NAME);
2664
2665 memset(filter, '\0', sizeof(filter));
2666 group_base = NULL;
2667 group_count = 0;
2668 if (rc = ad_get_group(ldap_handle, dn_path, group_name,
2669 group_membership, MoiraId,
2670 "distinguishedName", &group_base,
2671 &group_count, filter))
2672 return(rc);
2673
78af4e6e 2674 if (group_count != 1)
2675 {
f75f605a 2676 com_err(whoami, 0, "LDAP server unable to find list %s in AD",
2677 group_name);
2678 linklist_free(group_base);
2679 group_base = NULL;
2680 group_count = 0;
78af4e6e 2681 goto cleanup;
2682 }
2683 strcpy(distinguished_name, group_base->value);
2684 linklist_free(group_base);
2685 group_base = NULL;
2686 group_count = 0;
78af4e6e 2687
f75f605a 2688 sprintf(temp, "CN=%s,%s,%s", user_name, UserOu, dn_path);
2689 modvalues[0] = temp;
2690 modvalues[1] = NULL;
2691
2692 n = 0;
2693 ADD_ATTR("member", modvalues, LDAP_MOD_DELETE);
2694 mods[n] = NULL;
2695 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
2696 for (i = 0; i < n; i++)
2697 free(mods[i]);
6c8f12af 2698 if (rc == LDAP_UNWILLING_TO_PERFORM)
2699 rc = LDAP_SUCCESS;
f75f605a 2700 if (rc != LDAP_SUCCESS)
78af4e6e 2701 {
f75f605a 2702 com_err(whoami, 0, "LDAP server unable to modify list %s members : %s",
2703 group_name, ldap_err2string(rc));
2704 goto cleanup;
78af4e6e 2705 }
2706
2707cleanup:
78af4e6e 2708 return(rc);
2709}
2710
f75f605a 2711int member_add(LDAP *ldap_handle, char *dn_path, char *group_name,
89db421e 2712 char *group_ou, char *group_membership, char *user_name,
2713 char *UserOu, char *MoiraId)
cd9e6b16 2714{
2715 char distinguished_name[1024];
f75f605a 2716 char *modvalues[2];
cd9e6b16 2717 char temp[256];
89db421e 2718 char filter[128];
cd9e6b16 2719 int group_count;
cd9e6b16 2720 int n;
f75f605a 2721 int i;
cd9e6b16 2722 LDAPMod *mods[20];
2723 LK_ENTRY *group_base;
cd9e6b16 2724 ULONG rc;
2725
89db421e 2726 if (!check_string(group_name))
2727 return(AD_INVALID_NAME);
2728
cd9e6b16 2729 rc = 0;
89db421e 2730 memset(filter, '\0', sizeof(filter));
cd9e6b16 2731 group_base = NULL;
2732 group_count = 0;
89db421e 2733 if (rc = ad_get_group(ldap_handle, dn_path, group_name,
2734 group_membership, MoiraId,
2735 "distinguishedName", &group_base,
2736 &group_count, filter))
2737 return(rc);
cd9e6b16 2738
cd9e6b16 2739 if (group_count != 1)
2740 {
f75f605a 2741 linklist_free(group_base);
2742 group_base = NULL;
2743 group_count = 0;
2744 com_err(whoami, 0, "LDAP server unable to find list %s in AD",
2745 group_name);
89db421e 2746 return(AD_MULTIPLE_GROUPS_FOUND);
cd9e6b16 2747 }
f75f605a 2748
cd9e6b16 2749 strcpy(distinguished_name, group_base->value);
2750 linklist_free(group_base);
2751 group_base = NULL;
2752 group_count = 0;
2753
f75f605a 2754 sprintf(temp, "CN=%s,%s,%s", user_name, UserOu, dn_path);
2755 modvalues[0] = temp;
2756 modvalues[1] = NULL;
cd9e6b16 2757
f75f605a 2758 n = 0;
2759 ADD_ATTR("member", modvalues, LDAP_MOD_ADD);
2760 mods[n] = NULL;
2761 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
2762 if (rc == LDAP_ALREADY_EXISTS)
2763 rc = LDAP_SUCCESS;
89db421e 2764 if ((!strcmp(UserOu, contact_ou)) || (!strcmp(UserOu, kerberos_ou)))
2765 {
2766 if (rc == LDAP_UNWILLING_TO_PERFORM)
2767 rc = LDAP_SUCCESS;
2768 }
f75f605a 2769 for (i = 0; i < n; i++)
2770 free(mods[i]);
2771 if (rc != LDAP_SUCCESS)
cd9e6b16 2772 {
89db421e 2773 com_err(whoami, 0, "LDAP server unable to add %s to list %s as a member : %s",
2774 user_name, group_name, ldap_err2string(rc));
cd9e6b16 2775 }
2776
f75f605a 2777 return(rc);
cd9e6b16 2778}
2779
2780int contact_create(LDAP *ld, char *bind_path, char *user, char *group_ou)
2781{
2782 LDAPMod *mods[20];
2783 char new_dn[256];
2784 char cn_user_name[256];
2785 char contact_name[256];
f78c7eaf 2786 char *email_v[] = {NULL, NULL};
cd9e6b16 2787 char *cn_v[] = {NULL, NULL};
2788 char *contact_v[] = {NULL, NULL};
2789 char *objectClass_v[] = {"top", "person",
2790 "organizationalPerson",
2791 "contact", NULL};
2792 char *name_v[] = {NULL, NULL};
2793 char *desc_v[] = {NULL, NULL};
2794 int n;
2795 int rc;
2796 int i;
2797
2798 if (!check_string(user))
78af4e6e 2799 {
f75f605a 2800 com_err(whoami, 0, "invalid LDAP name %s", user);
89db421e 2801 return(AD_INVALID_NAME);
78af4e6e 2802 }
cd9e6b16 2803 strcpy(contact_name, user);
2804 sprintf(cn_user_name,"CN=%s,%s,%s", contact_name, group_ou, bind_path);
2805 cn_v[0] = cn_user_name;
2806 contact_v[0] = contact_name;
2807 name_v[0] = user;
2808 desc_v[0] = "Auto account created by Moira";
f78c7eaf 2809 email_v[0] = user;
cd9e6b16 2810
2811 strcpy(new_dn, cn_user_name);
2812 n = 0;
2813 ADD_ATTR("cn", contact_v, LDAP_MOD_ADD);
2814 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
2815 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
2816 ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
2817 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
f78c7eaf 2818 if (!strcmp(group_ou, contact_ou))
2819 {
2820 ADD_ATTR("mail", email_v, LDAP_MOD_ADD);
2821 }
cd9e6b16 2822 mods[n] = NULL;
2823
2824 rc = ldap_add_ext_s(ld, new_dn, mods, NULL, NULL);
2825 for (i = 0; i < n; i++)
2826 free(mods[i]);
f78c7eaf 2827 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
2828 {
2829 n = 0;
2830 ADD_ATTR("cn", contact_v, LDAP_MOD_ADD);
2831 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
2832 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
2833 ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
2834 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
2835 mods[n] = NULL;
2836 rc = ldap_add_ext_s(ld, new_dn, mods, NULL, NULL);
2837 for (i = 0; i < n; i++)
2838 free(mods[i]);
2839 }
cd9e6b16 2840 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
78af4e6e 2841 {
f75f605a 2842 com_err(whoami, 0, "could not create contact %s : %s",
2843 user, ldap_err2string(rc));
89db421e 2844 return(rc);
78af4e6e 2845 }
2846 return(0);
2847}
2848
f75f605a 2849int user_update(LDAP *ldap_handle, char *dn_path, char *user_name,
3abb4456 2850 char *Uid, char *MitId, char *MoiraId, int State,
2851 char *WinHomeDir, char *WinProfileDir)
78af4e6e 2852{
2853 LDAPMod *mods[20];
2854 LK_ENTRY *group_base;
2855 int group_count;
3abb4456 2856 char distinguished_name[512];
89db421e 2857 char *mitMoiraId_v[] = {NULL, NULL};
78af4e6e 2858 char *uid_v[] = {NULL, NULL};
2859 char *mitid_v[] = {NULL, NULL};
f78c7eaf 2860 char *homedir_v[] = {NULL, NULL};
2861 char *winProfile_v[] = {NULL, NULL};
2862 char *drives_v[] = {NULL, NULL};
89db421e 2863 char *userAccountControl_v[] = {NULL, NULL};
2864 char userAccountControlStr[80];
78af4e6e 2865 int n;
2866 int rc;
2867 int i;
3abb4456 2868 int OldUseSFU30;
89db421e 2869 u_int userAccountControl = UF_NORMAL_ACCOUNT | UF_DONT_EXPIRE_PASSWD | UF_PASSWD_CANT_CHANGE;
2870 char filter[128];
78af4e6e 2871 char *attr_array[3];
c0bd7667 2872 char temp[256];
78af4e6e 2873
f75f605a 2874 if (!check_string(user_name))
78af4e6e 2875 {
f75f605a 2876 com_err(whoami, 0, "invalid LDAP user name %s", user_name);
89db421e 2877 return(AD_INVALID_NAME);
78af4e6e 2878 }
2879
78af4e6e 2880 group_count = 0;
2881 group_base = NULL;
89db421e 2882
2883 if (strlen(MoiraId) != 0)
78af4e6e 2884 {
c0bd7667 2885 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
89db421e 2886 attr_array[0] = "cn";
2887 attr_array[1] = NULL;
2888 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
2889 &group_base, &group_count)) != 0)
2890 {
2891 com_err(whoami, 0, "LDAP server couldn't process user %s : %s",
2892 user_name, ldap_err2string(rc));
2893 return(rc);
2894 }
2895 }
c0bd7667 2896 if (group_count != 1)
89db421e 2897 {
c0bd7667 2898 linklist_free(group_base);
2899 group_base = NULL;
2900 group_count = 0;
89db421e 2901 sprintf(filter, "(sAMAccountName=%s)", user_name);
2902 attr_array[0] = "cn";
2903 attr_array[1] = NULL;
c0bd7667 2904 sprintf(temp, "%s,%s", user_ou, dn_path);
2905 if ((rc = linklist_build(ldap_handle, temp, filter, attr_array,
89db421e 2906 &group_base, &group_count)) != 0)
2907 {
2908 com_err(whoami, 0, "LDAP server couldn't process user %s : %s",
2909 user_name, ldap_err2string(rc));
2910 return(rc);
2911 }
78af4e6e 2912 }
2913
2914 if (group_count != 1)
2915 {
f75f605a 2916 com_err(whoami, 0, "LDAP server unable to find user %s in AD",
2917 user_name);
2918 linklist_free(group_base);
89db421e 2919 return(AD_NO_USER_FOUND);
78af4e6e 2920 }
2921 strcpy(distinguished_name, group_base->dn);
2922
f75f605a 2923 linklist_free(group_base);
2924 group_count = 0;
78af4e6e 2925 n = 0;
89db421e 2926 uid_v[0] = Uid;
2927 if (strlen(Uid) == 0)
2928 uid_v[0] = NULL;
2929 ADD_ATTR("uid", uid_v, LDAP_MOD_REPLACE);
3abb4456 2930 if (!UseSFU30)
2931 {
2932 ADD_ATTR("uidNumber", uid_v, LDAP_MOD_REPLACE);
2933 }
2934 else
2935 {
2936 ADD_ATTR("msSFU30UidNumber", uid_v, LDAP_MOD_REPLACE);
2937 }
89db421e 2938 mitid_v[0] = MitId;
2939 if (strlen(MitId) == 0)
2940 mitid_v[0] = NULL;
2941 ADD_ATTR("employeeID", mitid_v, LDAP_MOD_REPLACE);
2942 mitMoiraId_v[0] = MoiraId;
2943 if (strlen(MoiraId) == 0)
2944 mitMoiraId_v[0] = NULL;
2945 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_REPLACE);
2946 if ((State != US_NO_PASSWD) && (State != US_REGISTERED))
2947 userAccountControl |= UF_ACCOUNTDISABLE;
2948 sprintf(userAccountControlStr, "%ld", userAccountControl);
2949 userAccountControl_v[0] = userAccountControlStr;
2950 ADD_ATTR("userAccountControl", userAccountControl_v, LDAP_MOD_REPLACE);
3abb4456 2951
2952 n = SetHomeDirectory(ldap_handle, user_name, distinguished_name, WinHomeDir,
2953 WinProfileDir, homedir_v, winProfile_v,
2954 drives_v, mods, LDAP_MOD_REPLACE, n);
2955
78af4e6e 2956 mods[n] = NULL;
89db421e 2957 if ((rc = ldap_modify_s(ldap_handle, distinguished_name, mods)) != LDAP_SUCCESS)
78af4e6e 2958 {
3abb4456 2959 OldUseSFU30 = UseSFU30;
2960 SwitchSFU(mods, &UseSFU30, n);
2961 if (OldUseSFU30 != UseSFU30)
2962 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
2963 if (rc)
f78c7eaf 2964 {
3abb4456 2965 com_err(whoami, 0, "Couldn't modify user data for %s : %s",
2966 user_name, ldap_err2string(rc));
f78c7eaf 2967 }
2968 }
3abb4456 2969 for (i = 0; i < n; i++)
2970 free(mods[i]);
f75f605a 2971 return(rc);
cd9e6b16 2972}
2973
f75f605a 2974int user_rename(LDAP *ldap_handle, char *dn_path, char *before_user_name,
89db421e 2975 char *user_name)
9db0b148 2976{
2977 LDAPMod *mods[20];
2978 char new_dn[256];
2979 char old_dn[256];
9db0b148 2980 char upn[256];
2981 char temp[128];
2982 char *userPrincipalName_v[] = {NULL, NULL};
2983 char *altSecurityIdentities_v[] = {NULL, NULL};
2984 char *name_v[] = {NULL, NULL};
78af4e6e 2985 char *samAccountName_v[] = {NULL, NULL};
9db0b148 2986 int n;
2987 int rc;
2988 int i;
9db0b148 2989
f75f605a 2990 if (!check_string(before_user_name))
78af4e6e 2991 {
f75f605a 2992 com_err(whoami, 0, "invalid LDAP user name %s", before_user_name);
89db421e 2993 return(AD_INVALID_NAME);
78af4e6e 2994 }
f75f605a 2995 if (!check_string(user_name))
78af4e6e 2996 {
f75f605a 2997 com_err(whoami, 0, "invalid LDAP user name %s", user_name);
89db421e 2998 return(AD_INVALID_NAME);
78af4e6e 2999 }
9db0b148 3000
f75f605a 3001 strcpy(user_name, user_name);
3002 sprintf(old_dn, "cn=%s,%s,%s", before_user_name, user_ou, dn_path);
9db0b148 3003 sprintf(new_dn, "cn=%s", user_name);
f75f605a 3004 if ((rc = ldap_rename_s(ldap_handle, old_dn, new_dn, NULL, TRUE,
9db0b148 3005 NULL, NULL)) != LDAP_SUCCESS)
3006 {
89db421e 3007 com_err(whoami, 0, "Couldn't rename user from %s to %s : %s",
3008 before_user_name, user_name, ldap_err2string(rc));
f75f605a 3009 return(rc);
9db0b148 3010 }
3011
3012 name_v[0] = user_name;
3013 sprintf(upn, "%s@%s", user_name, ldap_domain);
3014 userPrincipalName_v[0] = upn;
3015 sprintf(temp, "Kerberos:%s@%s", user_name, PRIMARY_REALM);
3016 altSecurityIdentities_v[0] = temp;
78af4e6e 3017 samAccountName_v[0] = user_name;
9db0b148 3018
3019 n = 0;
3020 ADD_ATTR("altSecurityIdentities", altSecurityIdentities_v, LDAP_MOD_REPLACE);
3021 ADD_ATTR("userPrincipalName", userPrincipalName_v, LDAP_MOD_REPLACE);
3022 ADD_ATTR("displayName", name_v, LDAP_MOD_REPLACE);
78af4e6e 3023 ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_REPLACE);
9db0b148 3024 mods[n] = NULL;
f75f605a 3025 sprintf(new_dn, "cn=%s,%s,%s", user_name, user_ou, dn_path);
3026 if ((rc = ldap_modify_s(ldap_handle, new_dn, mods)) != LDAP_SUCCESS)
9db0b148 3027 {
f75f605a 3028 com_err(whoami, 0, "After renaming, couldn't modify user data for %s : %s",
3029 user_name, ldap_err2string(rc));
9db0b148 3030 }
3031 for (i = 0; i < n; i++)
3032 free(mods[i]);
f75f605a 3033 return(rc);
9db0b148 3034}
3035
f75f605a 3036int filesys_process(LDAP *ldap_handle, char *dn_path, char *fs_name,
3037 char *fs_type, char *fs_pack, int operation)
f78c7eaf 3038{
3039 char distinguished_name[256];
3040 char winPath[256];
3041 char winProfile[256];
89db421e 3042 char filter[128];
f78c7eaf 3043 char *attr_array[3];
3044 char *homedir_v[] = {NULL, NULL};
3045 char *winProfile_v[] = {NULL, NULL};
3046 char *drives_v[] = {NULL, NULL};
f78c7eaf 3047 int group_count;
3048 int n;
3049 int rc;
3050 int i;
f78c7eaf 3051 LDAPMod *mods[20];
3052 LK_ENTRY *group_base;
3053
f75f605a 3054 if (!check_string(fs_name))
f78c7eaf 3055 {
f75f605a 3056 com_err(whoami, 0, "invalid filesys name %s", fs_name);
89db421e 3057 return(AD_INVALID_NAME);
f78c7eaf 3058 }
3059
f75f605a 3060 if (strcmp(fs_type, "AFS"))
f78c7eaf 3061 {
f75f605a 3062 com_err(whoami, 0, "invalid filesys type %s", fs_type);
89db421e 3063 return(AD_INVALID_FILESYS);
f78c7eaf 3064 }
3065
f78c7eaf 3066 group_count = 0;
3067 group_base = NULL;
89db421e 3068 sprintf(filter, "(sAMAccountName=%s)", fs_name);
f78c7eaf 3069 attr_array[0] = "cn";
3070 attr_array[1] = NULL;
89db421e 3071 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
f78c7eaf 3072 &group_base, &group_count)) != 0)
3073 {
f75f605a 3074 com_err(whoami, 0, "LDAP server couldn't process filesys %s : %s",
3075 fs_name, ldap_err2string(rc));
3076 return(rc);
f78c7eaf 3077 }
3078
3079 if (group_count != 1)
3080 {
f75f605a 3081 linklist_free(group_base);
3082 com_err(whoami, 0, "LDAP server unable to find user %s in AD",
3083 fs_name);
3084 return(LDAP_NO_SUCH_OBJECT);
f78c7eaf 3085 }
3086 strcpy(distinguished_name, group_base->dn);
f75f605a 3087 linklist_free(group_base);
3088 group_count = 0;
f78c7eaf 3089
3090 n = 0;
3091 if (operation == LDAP_MOD_ADD)
3092 {
3093 memset(winPath, 0, sizeof(winPath));
f75f605a 3094 AfsToWinAfs(fs_pack, winPath);
f78c7eaf 3095 homedir_v[0] = winPath;
3096 drives_v[0] = "H:";
3097 memset(winProfile, 0, sizeof(winProfile));
3098 strcpy(winProfile, winPath);
3099 strcat(winProfile, "\\.winprofile");
3100 winProfile_v[0] = winProfile;
3101 }
3102 else
3103 {
3104 homedir_v[0] = NULL;
3105 drives_v[0] = NULL;
3106 winProfile_v[0] = NULL;
3107 }
3108 ADD_ATTR("profilePath", winProfile_v, operation);
3109 ADD_ATTR("homeDrive", drives_v, operation);
3110 ADD_ATTR("homeDirectory", homedir_v, operation);
3111 mods[n] = NULL;
3112
f75f605a 3113 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
f78c7eaf 3114 if (rc != LDAP_SUCCESS)
3115 {
f75f605a 3116 com_err(whoami, 0, "Couldn't modify user data for filesys %s : %s",
3117 fs_name, ldap_err2string(rc));
f78c7eaf 3118 }
3119 for (i = 0; i < n; i++)
3120 free(mods[i]);
3121
f75f605a 3122 return(rc);
f78c7eaf 3123}
3124
cd9e6b16 3125int user_create(int ac, char **av, void *ptr)
3126{
5b8457c5 3127 LK_ENTRY *group_base;
cd9e6b16 3128 LDAPMod *mods[20];
3129 char new_dn[256];
3130 char user_name[256];
9db0b148 3131 char sam_name[256];
5b8457c5 3132 char upn[256];
cd9e6b16 3133 char *cn_v[] = {NULL, NULL};
3134 char *objectClass_v[] = {"top", "person",
3135 "organizationalPerson",
3136 "user", NULL};
3137
3138 char *samAccountName_v[] = {NULL, NULL};
3139 char *altSecurityIdentities_v[] = {NULL, NULL};
89db421e 3140 char *mitMoiraId_v[] = {NULL, NULL};
cd9e6b16 3141 char *name_v[] = {NULL, NULL};
3142 char *desc_v[] = {NULL, NULL};
cd9e6b16 3143 char *userPrincipalName_v[] = {NULL, NULL};
3144 char *userAccountControl_v[] = {NULL, NULL};
78af4e6e 3145 char *uid_v[] = {NULL, NULL};
3146 char *mitid_v[] = {NULL, NULL};
3abb4456 3147 char *homedir_v[] = {NULL, NULL};
3148 char *winProfile_v[] = {NULL, NULL};
3149 char *drives_v[] = {NULL, NULL};
cd9e6b16 3150 char userAccountControlStr[80];
3151 char temp[128];
3152 u_int userAccountControl = UF_NORMAL_ACCOUNT | UF_DONT_EXPIRE_PASSWD | UF_PASSWD_CANT_CHANGE;
3153 int n;
3154 int rc;
3155 int i;
5b8457c5 3156 int group_count;
3abb4456 3157 int OldUseSFU30;
89db421e 3158 char filter[128];
cd9e6b16 3159 char *attr_array[3];
3160 char **call_args;
3abb4456 3161 char WinHomeDir[1024];
3162 char WinProfileDir[1024];
cd9e6b16 3163
3164 call_args = ptr;
3165
78af4e6e 3166 if (!check_string(av[U_NAME]))
3167 {
89db421e 3168 callback_rc = AD_INVALID_NAME;
f75f605a 3169 com_err(whoami, 0, "invalid LDAP user name %s", av[U_NAME]);
89db421e 3170 return(AD_INVALID_NAME);
78af4e6e 3171 }
9db0b148 3172
3abb4456 3173 memset(WinHomeDir, '\0', sizeof(WinHomeDir));
3174 memset(WinProfileDir, '\0', sizeof(WinProfileDir));
3175 strcpy(WinHomeDir, av[U_WINHOMEDIR]);
3176 strcpy(WinProfileDir, av[U_WINPROFILEDIR]);
cd9e6b16 3177 strcpy(user_name, av[U_NAME]);
3178 sprintf(upn, "%s@%s", user_name, ldap_domain);
78af4e6e 3179 sprintf(sam_name, "%s", av[U_NAME]);
9db0b148 3180 samAccountName_v[0] = sam_name;
89db421e 3181 if ((atoi(av[U_STATE]) != US_NO_PASSWD) && (atoi(av[U_STATE]) != US_REGISTERED))
cd9e6b16 3182 userAccountControl |= UF_ACCOUNTDISABLE;
3183 sprintf(userAccountControlStr, "%ld", userAccountControl);
3184 userAccountControl_v[0] = userAccountControlStr;
3185 userPrincipalName_v[0] = upn;
3186
3187 cn_v[0] = user_name;
3188 name_v[0] = user_name;
3189 desc_v[0] = "Auto account created by Moira";
3190 sprintf(temp, "Kerberos:%s@%s", user_name, PRIMARY_REALM);
3191 altSecurityIdentities_v[0] = temp;
3192 sprintf(new_dn, "cn=%s,%s,%s", user_name, user_ou, call_args[1]);
3193
3194 n = 0;
3195 ADD_ATTR("cn", cn_v, LDAP_MOD_ADD);
3196 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
3197 ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_ADD);
3198 ADD_ATTR("userPrincipalName", userPrincipalName_v, LDAP_MOD_ADD);
3199 ADD_ATTR("userAccountControl", userAccountControl_v, LDAP_MOD_ADD);
3200 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
3201 ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
3202 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
3abb4456 3203 if (strlen(call_args[2]) != 0)
89db421e 3204 {
3205 mitMoiraId_v[0] = call_args[2];
3206 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_ADD);
3207 }
cd9e6b16 3208 ADD_ATTR("altSecurityIdentities", altSecurityIdentities_v, LDAP_MOD_ADD);
78af4e6e 3209 if (strlen(av[U_UID]) != 0)
3210 {
3211 uid_v[0] = av[U_UID];
3212 ADD_ATTR("uid", uid_v, LDAP_MOD_ADD);
3abb4456 3213 if (!UseSFU30)
3214 {
3215 ADD_ATTR("uidNumber", uid_v, LDAP_MOD_ADD);
3216 }
3217 else
3218 {
3219 ADD_ATTR("msSFU30UidNumber", uid_v, LDAP_MOD_ADD);
3220 }
78af4e6e 3221 }
3222 if (strlen(av[U_MITID]) != 0)
3223 mitid_v[0] = av[U_MITID];
3224 else
3225 mitid_v[0] = "none";
3226 ADD_ATTR("employeeID", mitid_v, LDAP_MOD_ADD);
3abb4456 3227
3228 n = SetHomeDirectory((LDAP *)call_args[0], user_name, new_dn, WinHomeDir,
3229 WinProfileDir, homedir_v, winProfile_v,
3230 drives_v, mods, LDAP_MOD_ADD, n);
3231
cd9e6b16 3232 mods[n] = NULL;
3233
3234 rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL);
3abb4456 3235 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
3236 {
3237 OldUseSFU30 = UseSFU30;
3238 SwitchSFU(mods, &UseSFU30, n);
3239 if (OldUseSFU30 != UseSFU30)
3240 rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL);
3241 }
3242
78af4e6e 3243 for (i = 0; i < n; i++)
3244 free(mods[i]);
5b8457c5 3245 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
3246 {
3247 com_err(whoami, 0, "could not create user %s : %s",
3248 user_name, ldap_err2string(rc));
3249 callback_rc = rc;
3250 return(rc);
3251 }
cd9e6b16 3252 if (rc == LDAP_SUCCESS)
3253 {
f78c7eaf 3254 if ((rc = set_password(sam_name, "", ldap_domain)) != 0)
cd9e6b16 3255 {
f75f605a 3256 com_err(whoami, 0, "Couldn't set password for user %s : %ld",
3257 user_name, rc);
cd9e6b16 3258 }
3259 }
89db421e 3260 sprintf(filter, "(sAMAccountName=%s)", av[U_NAME]);
3261 if (strlen(call_args[2]) != 0)
c0bd7667 3262 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", call_args[2]);
cd9e6b16 3263 attr_array[0] = "objectSid";
3264 attr_array[1] = NULL;
5b8457c5 3265 group_count = 0;
3266 group_base = NULL;
89db421e 3267 if ((rc = linklist_build((LDAP *)call_args[0], call_args[1], filter, attr_array,
5b8457c5 3268 &group_base, &group_count)) == LDAP_SUCCESS)
cd9e6b16 3269 {
3e586ecf 3270 if (group_count != 1)
3271 {
3272 if (strlen(call_args[2]) != 0)
3273 {
3274 linklist_free(group_base);
3275 group_count = 0;
3276 group_base = NULL;
3277 sprintf(filter, "(sAMAccountName=%s)", av[U_NAME]);
3278 rc = linklist_build((LDAP *)call_args[0], call_args[1], filter,
3279 attr_array, &group_base, &group_count);
3280 }
3281 }
5b8457c5 3282 if (group_count == 1)
cd9e6b16 3283 {
5b8457c5 3284 (*sid_ptr) = group_base;
3e586ecf 3285 (*sid_ptr)->member = strdup(av[U_NAME]);
5b8457c5 3286 (*sid_ptr)->type = (char *)GROUPS;
cd9e6b16 3287 sid_ptr = &(*sid_ptr)->next;
3288 }
5b8457c5 3289 else
3290 {
3291 if (group_base != NULL)
3292 linklist_free(group_base);
3293 }
3294 }
3295 else
3296 {
3297 if (group_base != NULL)
3298 linklist_free(group_base);
cd9e6b16 3299 }
78af4e6e 3300 return(0);
cd9e6b16 3301}
3302
89db421e 3303int user_change_status(LDAP *ldap_handle, char *dn_path,
3304 char *user_name, char *MoiraId,
3305 int operation)
cd9e6b16 3306{
89db421e 3307 char filter[128];
cd9e6b16 3308 char *attr_array[3];
3309 char temp[256];
3310 char distinguished_name[1024];
cd9e6b16 3311 char **modvalues;
89db421e 3312 char *mitMoiraId_v[] = {NULL, NULL};
cd9e6b16 3313 LDAPMod *mods[20];
3314 LK_ENTRY *group_base;
3315 int group_count;
3316 int rc;
3317 int i;
3318 int n;
3319 ULONG ulongValue;
3320
f75f605a 3321 if (!check_string(user_name))
78af4e6e 3322 {
f75f605a 3323 com_err(whoami, 0, "invalid LDAP user name %s", user_name);
89db421e 3324 return(AD_INVALID_NAME);
78af4e6e 3325 }
f75f605a 3326
cd9e6b16 3327 group_count = 0;
3328 group_base = NULL;
89db421e 3329
3330 if (strlen(MoiraId) != 0)
cd9e6b16 3331 {
c0bd7667 3332 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
89db421e 3333 attr_array[0] = "UserAccountControl";
3334 attr_array[1] = NULL;
3335 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
3336 &group_base, &group_count)) != 0)
3337 {
3338 com_err(whoami, 0, "LDAP server couldn't process user %s : %s",
3339 user_name, ldap_err2string(rc));
3340 return(rc);
3341 }
3342 }
c0bd7667 3343 if (group_count != 1)
89db421e 3344 {
c0bd7667 3345 linklist_free(group_base);
3346 group_count = 0;
3347 group_base = NULL;
89db421e 3348 sprintf(filter, "(sAMAccountName=%s)", user_name);
3349 attr_array[0] = "UserAccountControl";
3350 attr_array[1] = NULL;
3351 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
3352 &group_base, &group_count)) != 0)
3353 {
3354 com_err(whoami, 0, "LDAP server couldn't process user %s : %s",
3355 user_name, ldap_err2string(rc));
3356 return(rc);
3357 }
cd9e6b16 3358 }
3359
78af4e6e 3360 if (group_count != 1)
cd9e6b16 3361 {
f75f605a 3362 linklist_free(group_base);
3363 com_err(whoami, 0, "LDAP server unable to find user %s in AD",
3364 user_name);
3365 return(LDAP_NO_SUCH_OBJECT);
cd9e6b16 3366 }
3367
3368 strcpy(distinguished_name, group_base->dn);
3369 ulongValue = atoi((*group_base).value);
3370 if (operation == MEMBER_DEACTIVATE)
3371 ulongValue |= UF_ACCOUNTDISABLE;
3372 else
3373 ulongValue &= ~UF_ACCOUNTDISABLE;
3374 sprintf(temp, "%ld", ulongValue);
3375 if ((rc = construct_newvalues(group_base, group_count, (*group_base).value,
3376 temp, &modvalues, REPLACE)) == 1)
f75f605a 3377 goto cleanup;
cd9e6b16 3378 linklist_free(group_base);
3379 group_base = NULL;
3380 group_count = 0;
3381 n = 0;
3382 ADD_ATTR("UserAccountControl", modvalues, LDAP_MOD_REPLACE);
89db421e 3383 if (strlen(MoiraId) != 0)
3384 {
3385 mitMoiraId_v[0] = MoiraId;
3386 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_REPLACE);
3387 }
cd9e6b16 3388 mods[n] = NULL;
f75f605a 3389 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
cd9e6b16 3390 for (i = 0; i < n; i++)
3391 free(mods[i]);
3392 free_values(modvalues);
3393 if (rc != LDAP_SUCCESS)
3394 {
f75f605a 3395 com_err(whoami, 0, "LDAP server could not change status of user %s : %s",
3396 user_name, ldap_err2string(rc));
cd9e6b16 3397 }
3398cleanup:
f75f605a 3399 return(rc);
cd9e6b16 3400}
3401
89db421e 3402int user_delete(LDAP *ldap_handle, char *dn_path,
3403 char *u_name, char *MoiraId)
cd9e6b16 3404{
89db421e 3405 char filter[128];
cd9e6b16 3406 char *attr_array[3];
3407 char distinguished_name[1024];
3408 char user_name[512];
3409 LK_ENTRY *group_base;
3410 int group_count;
3411 int rc;
3412
3413 if (!check_string(u_name))
89db421e 3414 return(AD_INVALID_NAME);
3415
cd9e6b16 3416 strcpy(user_name, u_name);
3417 group_count = 0;
3418 group_base = NULL;
89db421e 3419
3420 if (strlen(MoiraId) != 0)
cd9e6b16 3421 {
c0bd7667 3422 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
89db421e 3423 attr_array[0] = "name";
3424 attr_array[1] = NULL;
3425 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
3426 &group_base, &group_count)) != 0)
3427 {
3428 com_err(whoami, 0, "LDAP server couldn't process user %s : %s",
3429 user_name, ldap_err2string(rc));
3430 goto cleanup;
3431 }
3432 }
c0bd7667 3433 if (group_count != 1)
89db421e 3434 {
c0bd7667 3435 linklist_free(group_base);
3436 group_count = 0;
3437 group_base = NULL;
89db421e 3438 sprintf(filter, "(sAMAccountName=%s)", user_name);
3439 attr_array[0] = "name";
3440 attr_array[1] = NULL;
3441 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
3442 &group_base, &group_count)) != 0)
3443 {
3444 com_err(whoami, 0, "LDAP server couldn't process user %s : %s",
3445 user_name, ldap_err2string(rc));
3446 goto cleanup;
3447 }
cd9e6b16 3448 }
3449
78af4e6e 3450 if (group_count != 1)
cd9e6b16 3451 {
f75f605a 3452 com_err(whoami, 0, "LDAP server unable to find user %s in AD",
3453 user_name);
cd9e6b16 3454 goto cleanup;
3455 }
3456
3457 strcpy(distinguished_name, group_base->dn);
3458 if (rc = ldap_delete_s(ldap_handle, distinguished_name))
3459 {
f75f605a 3460 com_err(whoami, 0, "LDAP server couldn't process user %s : %s",
3461 user_name, ldap_err2string(rc));
cd9e6b16 3462 }
3463
3464cleanup:
3465 linklist_free(group_base);
78af4e6e 3466 return(0);
cd9e6b16 3467}
3468
3469void linklist_free(LK_ENTRY *linklist_base)
3470{
3471 LK_ENTRY *linklist_previous;
3472
3473 while (linklist_base != NULL)
3474 {
3475 if (linklist_base->dn != NULL)
3476 free(linklist_base->dn);
3477 if (linklist_base->attribute != NULL)
3478 free(linklist_base->attribute);
3479 if (linklist_base->value != NULL)
3480 free(linklist_base->value);
3481 if (linklist_base->member != NULL)
3482 free(linklist_base->member);
3483 if (linklist_base->type != NULL)
3484 free(linklist_base->type);
3485 if (linklist_base->list != NULL)
3486 free(linklist_base->list);
3487 linklist_previous = linklist_base;
3488 linklist_base = linklist_previous->next;
3489 free(linklist_previous);
3490 }
3491}
3492
3493void free_values(char **modvalues)
3494{
3495 int i;
3496
3497 i = 0;
3498 if (modvalues != NULL)
3499 {
3500 while (modvalues[i] != NULL)
3501 {
3502 free(modvalues[i]);
3503 modvalues[i] = NULL;
3504 ++i;
3505 }
3506 free(modvalues);
3507 }
3508}
3509
3510int sid_update(LDAP *ldap_handle, char *dn_path)
3511{
3512 LK_ENTRY *ptr;
3513 int rc;
3514 unsigned char temp[126];
3515 char *av[3];
3516
3517 ptr = sid_base;
3518
3519 while (ptr != NULL)
3520 {
3521 memset(temp, 0, sizeof(temp));
3522 convert_b_to_a(temp, ptr->value, ptr->length);
5b8457c5 3523 if (!ptr->member)
3524 continue;
cd9e6b16 3525 av[0] = ptr->member;
3526 av[1] = temp;
3527 if (ptr->type == (char *)GROUPS)
3528 {
3529 ptr->type = NULL;
3530 rc = mr_query("add_list_sid_by_name", 2, av, NULL, NULL);
3531 }
3532 else if (ptr->type == (char *)USERS)
3533 {
3534 ptr->type = NULL;
3535 rc = mr_query("add_user_sid_by_login", 2, av, NULL, NULL);
3536 }
3537 ptr = ptr->next;
3538 }
3539 return(0);
3540}
3541
3542void convert_b_to_a(char *string, UCHAR *binary, int length)
3543{
3544 int i;
3545 int j;
3546 UCHAR tmp;
3547
3548 j = 0;
3549 for (i = 0; i < length; i++)
3550 {
3551 tmp = binary[i];
3552 string[j] = tmp;
3553 string[j] >>= 4;
3554 string[j] &= 0x0f;
3555 string[j] += 0x30;
3556 if (string[j] > '9')
3557 string[j] += 0x27;
3558 ++j;
3559 string[j] = tmp & 0x0f;
3560 string[j] += 0x30;
3561 if (string[j] > '9')
3562 string[j] += 0x27;
3563 j++;
3564 }
3565 string[j] = 0;
3566}
3567
3568static int illegalchars[] = {
3569 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^@ - ^O */
3570 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^P - ^_ */
3571 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, /* SPACE - / */
3572 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, /* 0 - ? */
f75f605a 3573 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* @ - O */
cd9e6b16 3574 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, /* P - _ */
3575 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ` - o */
3576 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, /* p - ^? */
3577 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
3578 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
3579 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
3580 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
3581 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
3582 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
3583 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
3584 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
3585};
3586
3587int check_string(char *s)
3588{
78af4e6e 3589 char character;
3590
cd9e6b16 3591 for (; *s; s++)
3592 {
78af4e6e 3593 character = *s;
3594 if (isupper(character))
3595 character = tolower(character);
3596 if (illegalchars[(unsigned) character])
cd9e6b16 3597 return 0;
3598 }
3599 return 1;
3600}
3601
bb52f279 3602int check_container_name(char *s)
3603{
3604 char character;
3605
3606 for (; *s; s++)
3607 {
3608 character = *s;
3609 if (isupper(character))
3610 character = tolower(character);
3611
3612 if (character == ' ')
3613 continue;
3614 if (illegalchars[(unsigned) character])
3615 return 0;
3616 }
3617 return 1;
3618}
3619
cd9e6b16 3620int mr_connect_cl(char *server, char *client, int version, int auth)
3621{
984c91b7 3622 int status;
3623 char *motd;
3624 char temp[128];
cd9e6b16 3625
3626 status = mr_connect(server);
3627 if (status)
3628 {
3629 com_err(whoami, status, "while connecting to Moira");
aea5154c 3630 return status;
cd9e6b16 3631 }
3632
3633 status = mr_motd(&motd);
3634 if (status)
3635 {
3636 mr_disconnect();
3637 com_err(whoami, status, "while checking server status");
aea5154c 3638 return status;
cd9e6b16 3639 }
3640 if (motd)
3641 {
984c91b7 3642 sprintf(temp, "The Moira server is currently unavailable: %s", motd);
3643 com_err(whoami, status, temp);
cd9e6b16 3644 mr_disconnect();
aea5154c 3645 return status;
cd9e6b16 3646 }
3647
3648 status = mr_version(version);
3649 if (status)
3650 {
3651 if (status == MR_UNKNOWN_PROC)
f78c7eaf 3652 {
3653 if (version > 2)
3654 status = MR_VERSION_HIGH;
3655 else
3656 status = MR_SUCCESS;
3657 }
cd9e6b16 3658
3659 if (status == MR_VERSION_HIGH)
f78c7eaf 3660 {
3661 com_err(whoami, 0, "Warning: This client is running newer code than the server.");
3662 com_err(whoami, 0, "Some operations may not work.");
3663 }
cd9e6b16 3664 else if (status && status != MR_VERSION_LOW)
f78c7eaf 3665 {
3666 com_err(whoami, status, "while setting query version number.");
3667 mr_disconnect();
aea5154c 3668 return status;
f78c7eaf 3669 }
cd9e6b16 3670 }
3671
3672 if (auth)
3673 {
3674 status = mr_auth(client);
3675 if (status)
f78c7eaf 3676 {
3677 com_err(whoami, status, "while authenticating to Moira.");
3678 mr_disconnect();
aea5154c 3679 return status;
f78c7eaf 3680 }
cd9e6b16 3681 }
3682
aea5154c 3683 return MR_SUCCESS;
cd9e6b16 3684}
3685
f78c7eaf 3686void AfsToWinAfs(char* path, char* winPath)
3687{
3688 char* pathPtr;
3689 char* winPathPtr;
3690 strcpy(winPath, WINAFS);
3691 pathPtr = path + strlen(AFS);
3692 winPathPtr = winPath + strlen(WINAFS);
3693
3694 while (*pathPtr)
3695 {
3696 if (*pathPtr == '/')
3697 *winPathPtr = '\\';
3698 else
3699 *winPathPtr = *pathPtr;
3700
3701 pathPtr++;
3702 winPathPtr++;
3703 }
3704}
89db421e 3705
909e0dc3 3706int GetAceInfo(int ac, char **av, void *ptr)
3707{
3708 char **call_args;
3709 int security_flag;
3710
3711 call_args = ptr;
3712
3713 strcpy(call_args[0], av[L_ACE_TYPE]);
3714 strcpy(call_args[1], av[L_ACE_NAME]);
3715 security_flag = 0;
3716 get_group_membership(call_args[2], call_args[3], &security_flag, av);
3717 return(LDAP_SUCCESS);
3718
3719}
3720
bbef4f93 3721int checkADname(LDAP *ldap_handle, char *dn_path, char *Name)
909e0dc3 3722{
3723 char filter[128];
3724 char *attr_array[3];
3725 int group_count;
3726 int rc;
3727 LK_ENTRY *group_base;
3728
3729 group_count = 0;
3730 group_base = NULL;
3731
3732 sprintf(filter, "(sAMAccountName=%s)", Name);
3733 attr_array[0] = "sAMAccountName";
3734 attr_array[1] = NULL;
3735 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
3736 &group_base, &group_count)) != 0)
3737 {
3738 com_err(whoami, 0, "LDAP server couldn't process ACE name %s : %s",
3739 Name, ldap_err2string(rc));
3740 return(1);
3741 }
3742
3743 linklist_free(group_base);
3744 group_base = NULL;
3745 if (group_count == 0)
3746 return(0);
3747 return(1);
3748}
3749
3750#define MAX_ACE 7
3751
3752int ProcessAce(LDAP *ldap_handle, char *dn_path, char *Name, char *Type, int UpdateGroup, int *ProcessGroup)
3753{
3754 char *av[2];
3755 char GroupName[256];
3756 char *call_args[7];
3757 int rc;
3758 char *AceInfo[4];
3759 char AceType[32];
3760 char AceName[128];
3761 char AceMembership[2];
3762 char AceOu[256];
3763 char temp[128];
3764
3765 strcpy(GroupName, Name);
3766
3767 if (strcasecmp(Type, "LIST"))
3768 return(1);
3769 while (1)
3770 {
3771 av[0] = GroupName;
3772 AceInfo[0] = AceType;
3773 AceInfo[1] = AceName;
3774 AceInfo[2] = AceMembership;
3775 AceInfo[3] = AceOu;
3776 memset(AceType, '\0', sizeof(AceType));
3777 memset(AceName, '\0', sizeof(AceName));
3778 memset(AceMembership, '\0', sizeof(AceMembership));
3779 memset(AceOu, '\0', sizeof(AceOu));
3780 callback_rc = 0;
3781 if (rc = mr_query("get_list_info", 1, av, GetAceInfo, AceInfo))
3782 {
3783 com_err(whoami, 0, "Couldn't get ACE info for list %s : %s", GroupName, error_message(rc));
3784 return(1);
3785 }
3786 if (callback_rc)
3787 {
3788 com_err(whoami, 0, "Couldn't get ACE info for list %s", GroupName);
3789 return(1);
3790 }
3791 if ((strcasecmp(AceType, "USER")) && (strcasecmp(AceType, "LIST")))
3792 return(0);
3793 strcpy(temp, AceName);
3794 if (!strcasecmp(AceType, "LIST"))
3795 sprintf(temp, "%s_group", AceName);
3796 if (!UpdateGroup)
3797 {
bbef4f93 3798 if (checkADname(ldap_handle, dn_path, temp))
909e0dc3 3799 return(0);
3800 (*ProcessGroup) = 1;
3801 }
3802 if (!strcasecmp(AceInfo[0], "LIST"))
3803 {
3804 if (make_new_group(ldap_handle, dn_path, "", AceName, AceOu, AceMembership, 0, UpdateGroup))
3805 return(1);
3806 }
3807 else if (!strcasecmp(AceInfo[0], "USER"))
3808 {
3809 av[0] = AceName;
3810 call_args[0] = (char *)ldap_handle;
3811 call_args[1] = dn_path;
3812 call_args[2] = "";
3813 call_args[3] = NULL;
3814 sid_base = NULL;
3815 sid_ptr = &sid_base;
3816 callback_rc = 0;
3817 if (rc = mr_query("get_user_account_by_login", 1, av, user_create, call_args))
3818 {
3819 com_err(whoami, 0, "Couldn't process user ACE %s for group %s.", Name, AceName);
3820 return(1);
3821 }
3822 if (callback_rc)
3823 {
3824 com_err(whoami, 0, "Couldn't process user Ace %s for group %s", Name, AceName);
3825 return(1);
3826 }
3827 if (sid_base != NULL)
3828 {
3829 sid_update(ldap_handle, dn_path);
3830 linklist_free(sid_base);
3831 sid_base = NULL;
3832 }
3833 return(0);
3834 }
3835 else
3836 return(1);
3837 if (!strcasecmp(AceType, "LIST"))
3838 {
3839 if (!strcasecmp(GroupName, AceName))
3840 return(0);
3841 }
3842 strcpy(GroupName, AceName);
3843 }
3844 return(1);
3845}
3846
89db421e 3847int make_new_group(LDAP *ldap_handle, char *dn_path, char *MoiraId,
3848 char *group_name, char *group_ou, char *group_membership,
3849 int group_security_flag, int updateGroup)
3850{
3851 char *av[3];
3852 char *call_args[7];
3853 int rc;
3854
3855 av[0] = group_name;
3856 call_args[0] = (char *)ldap_handle;
3857 call_args[1] = dn_path;
3858 call_args[2] = group_name;
3859 call_args[3] = (char *)(MOIRA_USERS | MOIRA_KERBEROS | MOIRA_STRINGS);
3860 call_args[4] = (char *)updateGroup;
3861 call_args[5] = MoiraId;
3862 call_args[6] = NULL;
3863 sid_base = NULL;
3864 sid_ptr = &sid_base;
3865 callback_rc = 0;
3866 if (rc = mr_query("get_list_info", 1, av, group_create, call_args))
3867 {
3868 moira_disconnect();
3869 com_err(whoami, 0, "Couldn't create list %s : %s", group_name, error_message(rc));
3870 return(rc);
3871 }
3872 if (callback_rc)
3873 {
3874 moira_disconnect();
3875 com_err(whoami, 0, "Couldn't create list %s", group_name);
3876 return(callback_rc);
3877 }
3878
3879 if (sid_base != NULL)
3880 {
3881 sid_update(ldap_handle, dn_path);
3882 linklist_free(sid_base);
3883 sid_base = NULL;
3884 }
3885 return(0);
3886}
3887
3888int populate_group(LDAP *ldap_handle, char *dn_path, char *group_name,
3889 char *group_ou, char *group_membership,
3890 int group_security_flag, char *MoiraId)
3891{
3892 char *av[3];
3893 char *call_args[7];
3894 char *pUserOu;
3895 LK_ENTRY *ptr;
3896 int rc;
3897
3898 com_err(whoami, 0, "Populating group %s", group_name);
3899 av[0] = group_name;
3900 call_args[0] = (char *)ldap_handle;
3901 call_args[1] = dn_path;
3902 call_args[2] = group_name;
3903 call_args[3] = (char *)(MOIRA_USERS | MOIRA_KERBEROS | MOIRA_STRINGS);
3904 call_args[4] = NULL;
3905 member_base = NULL;
3906 if (rc = mr_query("get_end_members_of_list", 1, av,
3907 member_list_build, call_args))
3908 {
3909 com_err(whoami, 0, "Couldn't populate list %s : %s",
3910 group_name, error_message(rc));
3911 return(3);
3912 }
3913 if (member_base != NULL)
3914 {
3915 ptr = member_base;
3916 while (ptr != NULL)
3917 {
3918 if (!strcasecmp(ptr->type, "LIST"))
3919 {
3920 ptr = ptr->next;
3921 continue;
3922 }
3923 pUserOu = user_ou;
3924 if (!strcasecmp(ptr->type, "STRING"))
3925 {
3926 if (contact_create(ldap_handle, dn_path, ptr->member, contact_ou))
3927 return(3);
3928 pUserOu = contact_ou;
3929 }
3930 else if (!strcasecmp(ptr->type, "KERBEROS"))
3931 {
3932 if (contact_create(ldap_handle, dn_path, ptr->member, kerberos_ou))
3933 return(3);
3934 pUserOu = kerberos_ou;
3935 }
3936 rc = member_add(ldap_handle, dn_path, group_name,
3937 group_ou, group_membership, ptr->member,
3938 pUserOu, MoiraId);
3939 ptr = ptr->next;
3940 }
3941 linklist_free(member_base);
3942 member_base = NULL;
3943 }
3944 return(0);
3945}
3946
3947int process_group(LDAP *ldap_handle, char *dn_path, char *MoiraId,
3948 char *group_name, char *group_ou, char *group_membership,
3949 int group_security_flag, int type)
3950{
3951 char before_desc[512];
3952 char before_name[256];
3953 char before_group_ou[256];
3954 char before_group_membership[2];
3955 char distinguishedName[256];
3956 char ad_distinguishedName[256];
3957 char filter[128];
3958 char *attr_array[3];
3959 int before_security_flag;
3960 int group_count;
3961 int rc;
3962 LK_ENTRY *group_base;
3963 LK_ENTRY *ptr;
3964 char ou_both[512];
3965 char ou_security[512];
3966 char ou_distribution[512];
3967 char ou_neither[512];
3968
3969 memset(ad_distinguishedName, '\0', sizeof(ad_distinguishedName));
3970 sprintf(distinguishedName, "CN=%s,%s,%s", group_name, group_ou, dn_path);
3971
3972
3973 memset(filter, '\0', sizeof(filter));
3974 group_base = NULL;
3975 group_count = 0;
3976 if (rc = ad_get_group(ldap_handle, dn_path, group_name,
3977 "*", MoiraId,
3978 "distinguishedName", &group_base,
3979 &group_count, filter))
3980 return(rc);
3981
3982 if (type == CHECK_GROUPS)
3983 {
3984 if (group_count == 1)
3985 {
3986 if (!strcasecmp(group_base->value, distinguishedName))
3987 {
3988 linklist_free(group_base);
3989 return(0);
3990 }
3991 }
3992 linklist_free(group_base);
3993 if (group_count == 0)
3994 return(AD_NO_GROUPS_FOUND);
3995 if (group_count == 1)
3996 return(AD_WRONG_GROUP_DN_FOUND);
3997 return(AD_MULTIPLE_GROUPS_FOUND);
3998 }
3999 if (group_count == 0)
4000 {
4001 return(AD_NO_GROUPS_FOUND);
4002 }
4003 if (group_count > 1)
4004 {
4005 ptr = group_base;
4006 while (ptr != NULL)
4007 {
4008 if (!strcasecmp(distinguishedName, ptr->value))
4009 break;
4010 ptr = ptr->next;
4011 }
4012 if (ptr == NULL)
4013 {
4014 com_err(whoami, 0, "%d groups with moira id = %s", group_count, MoiraId);
4015 ptr = group_base;
4016 while (ptr != NULL)
4017 {
4018 com_err(whoami, 0, "%s with moira id = %s", ptr->value, MoiraId);
4019 ptr = ptr->next;
4020 }
4021 linklist_free(group_base);
4022 return(AD_MULTIPLE_GROUPS_FOUND);
6c8f12af 4023 }
89db421e 4024 ptr = group_base;
4025 while (ptr != NULL)
4026 {
4027 if (strcasecmp(distinguishedName, ptr->value))
4028 rc = ldap_delete_s(ldap_handle, ptr->value);
4029 ptr = ptr->next;
4030 }
4031 linklist_free(group_base);
4032 memset(filter, '\0', sizeof(filter));
4033 group_base = NULL;
4034 group_count = 0;
4035 if (rc = ad_get_group(ldap_handle, dn_path, group_name,
4036 "*", MoiraId,
4037 "distinguishedName", &group_base,
4038 &group_count, filter))
4039 return(rc);
4040 if (group_count == 0)
4041 return(AD_NO_GROUPS_FOUND);
4042 if (group_count > 1)
4043 return(AD_MULTIPLE_GROUPS_FOUND);
4044 }
4045
4046 strcpy(ad_distinguishedName, group_base->value);
4047 linklist_free(group_base);
4048 group_base = NULL;
4049 group_count = 0;
4050
4051 attr_array[0] = "sAMAccountName";
4052 attr_array[1] = NULL;
4053 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
4054 &group_base, &group_count)) != 0)
4055 {
4056 com_err(whoami, 0, "LDAP server unable to get list info with MoiraId = %s: %s",
4057 MoiraId, ldap_err2string(rc));
4058 return(rc);
4059 }
4060 sprintf(filter, "(sAMAccountName=%s)", group_base->value);
4061
4062 if (!strcasecmp(ad_distinguishedName, distinguishedName))
4063 {
4064 linklist_free(group_base);
4065 group_base = NULL;
4066 group_count = 0;
4067 return(0);
4068 }
4069 linklist_free(group_base);
4070 group_base = NULL;
4071 group_count = 0;
4072 memset(ou_both, '\0', sizeof(ou_both));
4073 memset(ou_security, '\0', sizeof(ou_security));
4074 memset(ou_distribution, '\0', sizeof(ou_distribution));
4075 memset(ou_neither, '\0', sizeof(ou_neither));
4076 memset(before_name, '\0', sizeof(before_name));
4077 memset(before_desc, '\0', sizeof(before_desc));
4078 memset(before_group_membership, '\0', sizeof(before_group_membership));
4079 attr_array[0] = "name";
4080 attr_array[1] = NULL;
4081 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
4082 &group_base, &group_count)) != 0)
4083 {
4084 com_err(whoami, 0, "LDAP server unable to get list name with MoiraId = %s: %s",
4085 MoiraId, ldap_err2string(rc));
4086 return(rc);
4087 }
4088 strcpy(before_name, group_base->value);
4089 linklist_free(group_base);
4090 group_base = NULL;
4091 group_count = 0;
4092 attr_array[0] = "description";
4093 attr_array[1] = NULL;
4094 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
4095 &group_base, &group_count)) != 0)
4096 {
4097 com_err(whoami, 0,
4098 "LDAP server unable to get list description with MoiraId = %s: %s",
4099 MoiraId, ldap_err2string(rc));
4100 return(rc);
4101 }
c0bd7667 4102 if (group_count != 0)
4103 {
4104 strcpy(before_desc, group_base->value);
4105 linklist_free(group_base);
4106 group_base = NULL;
4107 group_count = 0;
4108 }
89db421e 4109 change_to_lower_case(ad_distinguishedName);
4110 strcpy(ou_both, group_ou_both);
4111 change_to_lower_case(ou_both);
4112 strcpy(ou_security, group_ou_security);
4113 change_to_lower_case(ou_security);
4114 strcpy(ou_distribution, group_ou_distribution);
4115 change_to_lower_case(ou_distribution);
4116 strcpy(ou_neither, group_ou_neither);
4117 change_to_lower_case(ou_neither);
4118 if (strstr(ad_distinguishedName, ou_both))
4119 {
4120 strcpy(before_group_ou, group_ou_both);
4121 before_group_membership[0] = 'B';
4122 before_security_flag = 1;
4123 }
4124 else if (strstr(ad_distinguishedName, ou_security))
4125 {
4126 strcpy(before_group_ou, group_ou_security);
4127 before_group_membership[0] = 'S';
4128 before_security_flag = 1;
4129 }
4130 else if (strstr(ad_distinguishedName, ou_distribution))
4131 {
4132 strcpy(before_group_ou, group_ou_distribution);
4133 before_group_membership[0] = 'D';
4134 before_security_flag = 0;
4135 }
4136 else if (strstr(ad_distinguishedName, ou_neither))
4137 {
4138 strcpy(before_group_ou, group_ou_neither);
4139 before_group_membership[0] = 'N';
4140 before_security_flag = 0;
4141 }
4142 else
4143 return(AD_NO_OU_FOUND);
4144 rc = group_rename(ldap_handle, dn_path, before_name, before_group_membership,
4145 before_group_ou, before_security_flag, before_desc,
4146 group_name, group_membership, group_ou, group_security_flag,
4147 before_desc, MoiraId, filter);
4148 return(rc);
4149}
4150
4151void change_to_lower_case(char *ptr)
4152{
4153 int i;
4154
4155 for (i = 0; i < (int)strlen(ptr); i++)
4156 {
4157 ptr[i] = tolower(ptr[i]);
4158 }
4159}
4160
4161int ad_get_group(LDAP *ldap_handle, char *dn_path,
4162 char *group_name, char *group_membership,
4163 char *MoiraId, char *attribute,
4164 LK_ENTRY **linklist_base, int *linklist_count,
4165 char *rFilter)
4166{
3e586ecf 4167 LK_ENTRY *pPtr;
c0bd7667 4168 char filter[128];
4169 char *attr_array[3];
89db421e 4170 int rc;
4171
4172 (*linklist_base) = NULL;
4173 (*linklist_count) = 0;
4174 if (strlen(rFilter) != 0)
4175 {
4176 strcpy(filter, rFilter);
4177 attr_array[0] = attribute;
4178 attr_array[1] = NULL;
4179 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
4180 linklist_base, linklist_count)) != 0)
4181 {
4182 com_err(whoami, 0, "LDAP server unable to get list info with MoiraId = %s: %s",
4183 MoiraId, ldap_err2string(rc));
4184 return(rc);
4185 }
4186 if ((*linklist_count) == 1)
4187 {
4188 strcpy(rFilter, filter);
4189 return(0);
4190 }
4191 }
4192
4193 linklist_free((*linklist_base));
4194 (*linklist_base) = NULL;
4195 (*linklist_count) = 0;
4196 if (strlen(MoiraId) != 0)
4197 {
c0bd7667 4198 sprintf(filter, "(&(objectClass=group)(mitMoiraId=%s))", MoiraId);
89db421e 4199 attr_array[0] = attribute;
4200 attr_array[1] = NULL;
4201 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
4202 linklist_base, linklist_count)) != 0)
4203 {
4204 com_err(whoami, 0, "LDAP server unable to get list info with MoiraId = %s: %s",
4205 MoiraId, ldap_err2string(rc));
4206 return(rc);
4207 }
4208 }
3e586ecf 4209 if ((*linklist_count) > 1)
4210 {
4211 com_err(whoami, 0, "multiple groups with mitMoiraId = %s", MoiraId);
4212 pPtr = (*linklist_base);
4213 while (pPtr)
4214 {
4215 com_err(whoami, 0, "groups %s has mitMoiraId = %s", pPtr->value, MoiraId);
4216 pPtr = pPtr->next;
4217 }
4218 linklist_free((*linklist_base));
4219 (*linklist_base) = NULL;
4220 (*linklist_count) = 0;
4221 }
89db421e 4222 if ((*linklist_count) == 1)
4223 {
909e0dc3 4224 if (!memcmp(&(*linklist_base)->value[3], group_name, strlen(group_name)))
4225 {
4226 strcpy(rFilter, filter);
4227 return(0);
4228 }
89db421e 4229 }
4230
4231 linklist_free((*linklist_base));
4232 (*linklist_base) = NULL;
4233 (*linklist_count) = 0;
4234 sprintf(filter, "(sAMAccountName=%s_group)", group_name);
4235 attr_array[0] = attribute;
4236 attr_array[1] = NULL;
4237 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
4238 linklist_base, linklist_count)) != 0)
4239 {
4240 com_err(whoami, 0, "LDAP server unable to get list info with MoiraId = %s: %s",
4241 MoiraId, ldap_err2string(rc));
4242 return(rc);
4243 }
4244 if ((*linklist_count) == 1)
4245 {
4246 strcpy(rFilter, filter);
4247 return(0);
4248 }
4249
89db421e 4250 return(0);
4251}
4252
4253int check_user(LDAP *ldap_handle, char *dn_path, char *UserName, char *MoiraId)
4254{
4255 char filter[128];
4256 char *attr_array[3];
4257 char SamAccountName[64];
4258 int group_count;
4259 int rc;
4260 LK_ENTRY *group_base;
c0bd7667 4261 LK_ENTRY *gPtr;
89db421e 4262
4263 group_count = 0;
4264 group_base = NULL;
4265
4266 if (strlen(MoiraId) != 0)
4267 {
c0bd7667 4268 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
89db421e 4269 attr_array[0] = "sAMAccountName";
4270 attr_array[1] = NULL;
4271 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
4272 &group_base, &group_count)) != 0)
4273 {
4274 com_err(whoami, 0, "LDAP server couldn't process user %s : %s",
4275 UserName, ldap_err2string(rc));
4276 return(rc);
4277 }
c0bd7667 4278 if (group_count > 1)
4279 {
4280 com_err(whoami, 0, "multiple users exist with MoiraId = %s",
4281 MoiraId);
4282 gPtr = group_base;
4283 while (gPtr)
4284 {
4285 com_err(whoami, 0, "user %s exist with MoiraId = %s",
4286 gPtr->value, MoiraId);
4287 gPtr = gPtr->next;
4288 }
4289 }
89db421e 4290 }
c0bd7667 4291 if (group_count != 1)
89db421e 4292 {
c0bd7667 4293 linklist_free(group_base);
4294 group_count = 0;
4295 group_base = NULL;
89db421e 4296 sprintf(filter, "(sAMAccountName=%s)", UserName);
4297 attr_array[0] = "sAMAccountName";
4298 attr_array[1] = NULL;
4299 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
4300 &group_base, &group_count)) != 0)
4301 {
4302 com_err(whoami, 0, "LDAP server couldn't process user %s : %s",
4303 UserName, ldap_err2string(rc));
4304 return(rc);
4305 }
4306 }
4307
4308 if (group_count != 1)
4309 {
4310 linklist_free(group_base);
4311 return(AD_NO_USER_FOUND);
4312 }
4313 strcpy(SamAccountName, group_base->value);
4314 linklist_free(group_base);
4315 group_count = 0;
4316 rc = 0;
4317 if (strcmp(SamAccountName, UserName))
4318 {
4319 rc = user_rename(ldap_handle, dn_path, SamAccountName,
4320 UserName);
4321 }
4322 return(0);
4323}
6c8f12af 4324
4325void container_get_dn(char *src, char *dest)
4326{
4327 char *sPtr;
4328 char *array[20];
4329 char name[256];
4330 int n;
4331
4332 memset(array, '\0', 20 * sizeof(array[0]));
4333
4334 if (strlen(src) == 0)
4335 return;
4336 strcpy(name, src);
4337 sPtr = name;
4338 n = 0;
4339 array[n] = name;
4340 ++n;
4341 while (*sPtr)
4342 {
4343 if ((*sPtr) == '/')
4344 {
4345 (*sPtr) = '\0';
4346 ++sPtr;
4347 array[n] = sPtr;
4348 ++n;
4349 }
4350 else
4351 ++sPtr;
4352 }
4353 strcpy(dest, "OU=");
4354 while (n != 0)
4355 {
4356 strcat(dest, array[n-1]);
4357 --n;
4358 if (n > 0)
4359 {
4360 strcat(dest, ",OU=");
4361 }
4362 }
4363 return;
4364}
4365
4366void container_get_name(char *src, char *dest)
4367{
4368 char *sPtr;
4369 char *dPtr;
4370
4371 if (strlen(src) == 0)
4372 return;
4373 sPtr = src;
4374 dPtr = src;
4375 while (*sPtr)
4376 {
4377 if ((*sPtr) == '/')
4378 {
4379 dPtr = sPtr;
4380 ++dPtr;
4381 }
4382 ++sPtr;
4383 }
4384 strcpy(dest, dPtr);
4385 return;
4386}
4387
4388void container_check(LDAP *ldap_handle, char *dn_path, char *name)
4389{
4390 char cName[256];
4391 char *av[7];
4392 int i;
4393 int rc;
4394
4395 strcpy(cName, name);
4396 for (i = 0; i < (int)strlen(cName); i++)
4397 {
4398 if (cName[i] == '/')
4399 {
4400 cName[i] = '\0';
4401 av[CONTAINER_NAME] = cName;
4402 av[CONTAINER_DESC] = "";
4403 av[CONTAINER_LOCATION] = "";
4404 av[CONTAINER_CONTACT] = "";
4405 av[CONTAINER_TYPE] = "";
4406 av[CONTAINER_ID] = "";
4407 av[CONTAINER_ROWID] = "";
4408 rc = container_create(ldap_handle, dn_path, 7, av);
4409 if (rc == LDAP_SUCCESS)
4410 {
4411 com_err(whoami, 0, "container %s created without a mitMoiraId", cName);
4412 }
4413 cName[i] = '/';
4414 }
4415 }
4416
4417}
4418
4419int container_rename(LDAP *ldap_handle, char *dn_path, int beforec, char **before,
4420 int afterc, char **after)
4421{
4422 char dName[256];
4423 char cName[256];
4424 char new_cn[128];
4425 char new_dn_path[256];
4426 char temp[256];
4427 char distinguishedName[256];
4428 char *pPtr;
4429 int rc;
4430 int i;
4431
4432 memset(cName, '\0', sizeof(cName));
4433 container_get_name(after[CONTAINER_NAME], cName);
bb52f279 4434 if (!check_container_name(cName))
6c8f12af 4435 {
4436 com_err(whoami, 0, "invalid LDAP container name %s", cName);
4437 return(AD_INVALID_NAME);
4438 }
4439
4440 memset(distinguishedName, '\0', sizeof(distinguishedName));
4441 if (rc = container_get_distinguishedName(ldap_handle, dn_path, distinguishedName, beforec, before))
4442 return(rc);
4443 if (strlen(distinguishedName) == 0)
4444 {
4445 rc = container_create(ldap_handle, dn_path, afterc, after);
4446 return(rc);
4447 }
4448
4449 strcpy(temp, after[CONTAINER_NAME]);
9cfe334f 4450 pPtr = temp;
6c8f12af 4451 for (i = 0; i < (int)strlen(temp); i++)
4452 {
4453 if (temp[i] == '/')
4454 {
4455 pPtr = &temp[i];
4456 }
4457 }
9cfe334f 4458 (*pPtr) = '\0';
6c8f12af 4459
4460 container_get_dn(temp, dName);
9cfe334f 4461 if (strlen(temp) != 0)
4462 sprintf(new_dn_path, "%s,%s", dName, dn_path);
4463 else
4464 sprintf(new_dn_path, "%s", dn_path);
6c8f12af 4465 sprintf(new_cn, "OU=%s", cName);
4466
4467 container_check(ldap_handle, dn_path, after[CONTAINER_NAME]);
4468
4469 if ((rc = ldap_rename_s(ldap_handle, distinguishedName, new_cn, new_dn_path,
4470 TRUE, NULL, NULL)) != LDAP_SUCCESS)
4471 {
4472 com_err(whoami, 0, "couldn't rename container from %s to %s : %s",
4473 before[CONTAINER_NAME], after[CONTAINER_NAME], ldap_err2string(rc));
4474 return(rc);
4475 }
4476
4477 memset(dName, '\0', sizeof(dName));
4478 container_get_dn(after[CONTAINER_NAME], dName);
4479 rc = container_adupdate(ldap_handle, dn_path, dName, "", afterc, after);
4480 return(rc);
4481}
4482
4483int container_delete(LDAP *ldap_handle, char *dn_path, int count, char **av)
4484{
4485 char distinguishedName[256];
4486 int rc;
4487
4488 memset(distinguishedName, '\0', sizeof(distinguishedName));
4489 if (rc = container_get_distinguishedName(ldap_handle, dn_path, distinguishedName, count, av))
4490 return(rc);
4491 if (strlen(distinguishedName) == 0)
4492 return(0);
4493 if ((rc = ldap_delete_s(ldap_handle, distinguishedName)) != LDAP_SUCCESS)
4494 {
4495 if (rc == LDAP_NOT_ALLOWED_ON_NONLEAF)
4496 container_move_objects(ldap_handle, dn_path, distinguishedName);
4497 else
4498 com_err(whoami, 0, "unable to delete container %s from AD : %s",
4499 av[CONTAINER_NAME], ldap_err2string(rc));
4500 }
4501 return(rc);
4502}
bbef4f93 4503
6c8f12af 4504int container_create(LDAP *ldap_handle, char *dn_path, int count, char **av)
4505{
4506 char *attr_array[3];
4507 LK_ENTRY *group_base;
4508 int group_count;
4509 LDAPMod *mods[20];
4510 char *objectClass_v[] = {"top",
4511 "organizationalUnit",
4512 NULL};
4513
4514 char *ou_v[] = {NULL, NULL};
4515 char *name_v[] = {NULL, NULL};
4516 char *moiraId_v[] = {NULL, NULL};
4517 char *desc_v[] = {NULL, NULL};
4518 char *managedBy_v[] = {NULL, NULL};
4519 char dName[256];
4520 char cName[256];
4521 char managedByDN[256];
4522 char filter[256];
4523 char temp[256];
4524 int n;
4525 int i;
4526 int rc;
4527
4528 memset(filter, '\0', sizeof(filter));
4529 memset(dName, '\0', sizeof(dName));
4530 memset(cName, '\0', sizeof(cName));
4531 memset(managedByDN, '\0', sizeof(managedByDN));
4532 container_get_dn(av[CONTAINER_NAME], dName);
4533 container_get_name(av[CONTAINER_NAME], cName);
4534
4535 if ((strlen(cName) == 0) || (strlen(dName) == 0))
4536 {
4537 com_err(whoami, 0, "invalid LDAP container name %s", cName);
4538 return(AD_INVALID_NAME);
4539 }
4540
bb52f279 4541 if (!check_container_name(cName))
6c8f12af 4542 {
4543 com_err(whoami, 0, "invalid LDAP container name %s", cName);
4544 return(AD_INVALID_NAME);
4545 }
4546
4547 n = 0;
4548 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
4549 name_v[0] = cName;
4550 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
4551 ou_v[0] = cName;
4552 ADD_ATTR("ou", ou_v, LDAP_MOD_ADD);
4553 if (strlen(av[CONTAINER_ROWID]) != 0)
4554 {
4555 moiraId_v[0] = av[CONTAINER_ROWID];
4556 ADD_ATTR("mitMoiraId", moiraId_v, LDAP_MOD_ADD);
4557 }
4558 if (strlen(av[CONTAINER_DESC]) != 0)
4559 {
4560 desc_v[0] = av[CONTAINER_DESC];
4561 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
4562 }
4563 if ((strlen(av[CONTAINER_TYPE]) != 0) && (strlen(av[CONTAINER_ID]) != 0))
4564 {
0eae7c9b 4565 if (!strcasecmp(av[CONTAINER_TYPE], "KERBEROS"))
4566 {
4567 if (!contact_create(ldap_handle, dn_path, av[CONTAINER_ID], kerberos_ou))
4568 {
4569 sprintf(managedByDN, "CN=%s,%s,%s", av[CONTAINER_ID], kerberos_ou,dn_path);
4570 managedBy_v[0] = managedByDN;
4571 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_ADD);
4572 }
4573 }
4574 else
4575 {
4576 if (!strcasecmp(av[CONTAINER_TYPE], "USER"))
6c8f12af 4577 {
0eae7c9b 4578 sprintf(filter, "(&(cn=%s)(&(objectCategory=person)(objectClass=user)))", av[CONTAINER_ID]);
6c8f12af 4579 }
0eae7c9b 4580 if (!strcasecmp(av[CONTAINER_TYPE], "LIST"))
6c8f12af 4581 {
0eae7c9b 4582 sprintf(filter, "(&(objectClass=group)(cn=%s))", av[CONTAINER_ID]);
6c8f12af 4583 }
0eae7c9b 4584 if (strlen(filter) != 0)
6c8f12af 4585 {
4586 attr_array[0] = "distinguishedName";
4587 attr_array[1] = NULL;
4588 group_count = 0;
4589 group_base = NULL;
909e0dc3 4590 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6c8f12af 4591 &group_base, &group_count)) == LDAP_SUCCESS)
4592 {
4593 if (group_count == 1)
4594 {
4595 strcpy(managedByDN, group_base->value);
4596 managedBy_v[0] = managedByDN;
4597 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_ADD);
4598 }
4599 linklist_free(group_base);
4600 group_base = NULL;
4601 group_count = 0;
4602 }
4603 }
4604 }
0eae7c9b 4605 }
6c8f12af 4606 mods[n] = NULL;
4607
4608 sprintf(temp, "%s,%s", dName, dn_path);
4609 rc = ldap_add_ext_s(ldap_handle, temp, mods, NULL, NULL);
4610 for (i = 0; i < n; i++)
4611 free(mods[i]);
4612 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
4613 {
4614 com_err(whoami, 0, "couldn't create container %s : %s",
4615 cName, ldap_err2string(rc));
4616 return(rc);
4617 }
4618 if (rc == LDAP_ALREADY_EXISTS)
4619 {
4620 if (strlen(av[CONTAINER_ROWID]) != 0)
4621 rc = container_adupdate(ldap_handle, dn_path, dName, "", count, av);
4622 }
4623 return(rc);
4624}
4625
4626int container_update(LDAP *ldap_handle, char *dn_path, int beforec, char **before,
4627 int afterc, char **after)
4628{
4629 char distinguishedName[256];
4630 int rc;
4631
4632 memset(distinguishedName, '\0', sizeof(distinguishedName));
4633 if (rc = container_get_distinguishedName(ldap_handle, dn_path, distinguishedName, afterc, after))
4634 return(rc);
4635 if (strlen(distinguishedName) == 0)
4636 {
4637 rc = container_create(ldap_handle, dn_path, afterc, after);
4638 return(rc);
4639 }
4640
4641 container_check(ldap_handle, dn_path, after[CONTAINER_NAME]);
4642 rc = container_adupdate(ldap_handle, dn_path, "", distinguishedName, afterc, after);
4643
4644 return(rc);
4645}
4646
4647int container_get_distinguishedName(LDAP *ldap_handle, char *dn_path, char *distinguishedName, int count, char **av)
4648{
4649 char *attr_array[3];
4650 LK_ENTRY *group_base;
4651 int group_count;
4652 char dName[256];
4653 char cName[256];
4654 char filter[512];
4655 int rc;
4656
4657 memset(filter, '\0', sizeof(filter));
4658 memset(dName, '\0', sizeof(dName));
4659 memset(cName, '\0', sizeof(cName));
4660 container_get_dn(av[CONTAINER_NAME], dName);
4661 container_get_name(av[CONTAINER_NAME], cName);
4662
4663 if (strlen(dName) == 0)
4664 {
4665 com_err(whoami, 0, "invalid LDAP container name %s", av[CONTAINER_NAME]);
4666 return(AD_INVALID_NAME);
4667 }
4668
bb52f279 4669 if (!check_container_name(cName))
6c8f12af 4670 {
4671 com_err(whoami, 0, "invalid LDAP container name %s", cName);
4672 return(AD_INVALID_NAME);
4673 }
4674
4675 sprintf(filter, "(&(objectClass=organizationalUnit)(mitMoiraId=%s))", av[CONTAINER_ROWID]);
4676 attr_array[0] = "distinguishedName";
4677 attr_array[1] = NULL;
4678 group_count = 0;
4679 group_base = NULL;
4680 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
4681 &group_base, &group_count)) == LDAP_SUCCESS)
4682 {
4683 if (group_count == 1)
4684 {
4685 strcpy(distinguishedName, group_base->value);
4686 }
4687 linklist_free(group_base);
4688 group_base = NULL;
4689 group_count = 0;
4690 }
4691 if (strlen(distinguishedName) == 0)
4692 {
4693 sprintf(filter, "(&(objectClass=organizationalUnit)(distinguishedName=%s,%s))", dName, dn_path);
4694 attr_array[0] = "distinguishedName";
4695 attr_array[1] = NULL;
4696 group_count = 0;
4697 group_base = NULL;
4698 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
4699 &group_base, &group_count)) == LDAP_SUCCESS)
4700 {
4701 if (group_count == 1)
4702 {
4703 strcpy(distinguishedName, group_base->value);
4704 }
4705 linklist_free(group_base);
4706 group_base = NULL;
4707 group_count = 0;
4708 }
4709 }
4710 return(0);
4711}
4712
4713int container_adupdate(LDAP *ldap_handle, char *dn_path, char *dName,
4714 char *distinguishedName, int count, char **av)
4715{
4716 char *attr_array[5];
4717 LK_ENTRY *group_base;
4718 LK_ENTRY *pPtr;
4719 LDAPMod *mods[20];
4720 int group_count;
4721 char filter[512];
4722 char temp[256];
4723 char *moiraId_v[] = {NULL, NULL};
4724 char *desc_v[] = {NULL, NULL};
4725 char *managedBy_v[] = {NULL, NULL};
4726 char managedByDN[256];
4727 char moiraId[64];
4728 char desc[256];
4729 int rc;
4730 int i;
4731 int n;
4732
4733
4734 strcpy(temp, distinguishedName);
4735 if (strlen(dName) != 0)
4736 sprintf(temp, "%s,%s", dName, dn_path);
4737
4738 sprintf(filter, "(&(objectClass=organizationalUnit)(distinguishedName=%s))", temp);
4739 if (strlen(av[CONTAINER_ID]) != 0)
4740 sprintf(filter, "(&(objectClass=organizationalUnit)(mitMoiraId=%s))", av[CONTAINER_ROWID]);
4741 attr_array[0] = "mitMoiraId";
4742 attr_array[1] = "description";
4743 attr_array[2] = "managedBy";
4744 attr_array[3] = NULL;
4745 group_count = 0;
4746 group_base = NULL;
4747 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
4748 &group_base, &group_count)) != LDAP_SUCCESS)
4749 {
4750 com_err(whoami, 0, "couldn't retreive container info for %s : %s",
4751 av[CONTAINER_NAME], ldap_err2string(rc));
4752 return(rc);
4753 }
4754 memset(managedByDN, '\0', sizeof(managedByDN));
4755 memset(moiraId, '\0', sizeof(moiraId));
4756 memset(desc, '\0', sizeof(desc));
4757 pPtr = group_base;
4758 while (pPtr)
4759 {
4760 if (!strcasecmp(pPtr->attribute, "description"))
4761 strcpy(desc, pPtr->value);
9cfe334f 4762 else if (!strcasecmp(pPtr->attribute, "managedBy"))
6c8f12af 4763 strcpy(managedByDN, pPtr->value);
9cfe334f 4764 else if (!strcasecmp(pPtr->attribute, "mitMoiraId"))
6c8f12af 4765 strcpy(moiraId, pPtr->value);
4766 pPtr = pPtr->next;
4767 }
4768 linklist_free(group_base);
4769 group_base = NULL;
4770 group_count = 0;
4771
4772 n = 0;
4773 if (strlen(av[CONTAINER_ROWID]) != 0)
4774 {
4775 moiraId_v[0] = av[CONTAINER_ROWID];
4776 ADD_ATTR("mitMoiraId", moiraId_v, LDAP_MOD_REPLACE);
4777 }
4778 if (strlen(av[CONTAINER_DESC]) != 0)
4779 {
4780 desc_v[0] = av[CONTAINER_DESC];
4781 ADD_ATTR("description", desc_v, LDAP_MOD_REPLACE);
4782 }
4783 else
4784 {
4785 if (strlen(desc) != 0)
4786 {
4787 desc_v[0] = NULL;
4788 ADD_ATTR("description", desc_v, LDAP_MOD_REPLACE);
4789 }
4790 }
4791 if ((strlen(av[CONTAINER_TYPE]) != 0) && (strlen(av[CONTAINER_ID]) != 0))
4792 {
0eae7c9b 4793 if (!strcasecmp(av[CONTAINER_TYPE], "KERBEROS"))
4794 {
4795 if (!contact_create(ldap_handle, dn_path, av[CONTAINER_ID], kerberos_ou))
4796 {
4797 sprintf(managedByDN, "CN=%s,%s,%s", av[CONTAINER_ID], kerberos_ou, dn_path);
4798 managedBy_v[0] = managedByDN;
4799 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_REPLACE);
4800 }
4801 else
4802 {
4803 if (strlen(managedByDN) != 0)
4804 {
4805 managedBy_v[0] = NULL;
4806 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_REPLACE);
4807 }
4808 }
4809 }
4810 else
4811 {
4812 memset(filter, '\0', sizeof(filter));
4813 if (!strcasecmp(av[CONTAINER_TYPE], "USER"))
6c8f12af 4814 {
0eae7c9b 4815 sprintf(filter, "(&(cn=%s)(&(objectCategory=person)(objectClass=user)))", av[CONTAINER_ID]);
6c8f12af 4816 }
0eae7c9b 4817 if (!strcasecmp(av[CONTAINER_TYPE], "LIST"))
6c8f12af 4818 {
0eae7c9b 4819 sprintf(filter, "(&(objectClass=group)(cn=%s))", av[CONTAINER_ID]);
6c8f12af 4820 }
0eae7c9b 4821 if (strlen(filter) != 0)
6c8f12af 4822 {
4823 attr_array[0] = "distinguishedName";
4824 attr_array[1] = NULL;
4825 group_count = 0;
4826 group_base = NULL;
5f7b0741 4827 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6c8f12af 4828 &group_base, &group_count)) == LDAP_SUCCESS)
4829 {
4830 if (group_count == 1)
4831 {
4832 strcpy(managedByDN, group_base->value);
4833 managedBy_v[0] = managedByDN;
4834 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_REPLACE);
4835 }
4836 else
4837 {
4838 if (strlen(managedByDN) != 0)
4839 {
4840 managedBy_v[0] = NULL;
4841 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_REPLACE);
4842 }
4843 }
4844 linklist_free(group_base);
4845 group_base = NULL;
4846 group_count = 0;
4847 }
4848 }
0eae7c9b 4849 else
6c8f12af 4850 {
4851 if (strlen(managedByDN) != 0)
4852 {
4853 managedBy_v[0] = NULL;
4854 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_REPLACE);
4855 }
4856 }
0eae7c9b 4857 }
6c8f12af 4858 }
4859 mods[n] = NULL;
4860 if (n == 0)
4861 return(LDAP_SUCCESS);
4862
4863 strcpy(temp, distinguishedName);
4864 if (strlen(dName) != 0)
4865 sprintf(temp, "%s,%s", dName, dn_path);
4866 rc = ldap_modify_s(ldap_handle, temp, mods);
4867 for (i = 0; i < n; i++)
4868 free(mods[i]);
4869 if (rc != LDAP_SUCCESS)
4870 {
4871 com_err(whoami, 0, "couldn't modify container info for %s : %s",
4872 av[CONTAINER_NAME], ldap_err2string(rc));
4873 return(rc);
4874 }
4875 return(rc);
4876}
4877
4878int container_move_objects(LDAP *ldap_handle, char *dn_path, char *dName)
4879{
4880 char *attr_array[3];
4881 LK_ENTRY *group_base;
4882 LK_ENTRY *pPtr;
4883 int group_count;
4884 char filter[512];
4885 char new_cn[128];
4886 char temp[256];
4887 int rc;
4888 int NumberOfEntries = 10;
4889 int i;
4890 int count;
4891
4892 rc = ldap_set_option(ldap_handle, LDAP_OPT_SIZELIMIT, &NumberOfEntries);
4893
4894 for (i = 0; i < 3; i++)
4895 {
4896 memset(filter, '\0', sizeof(filter));
4897 if (i == 0)
4898 {
4899 strcpy(filter, "(!(|(objectClass=computer)(objectClass=organizationalUnit)))");
4900 attr_array[0] = "cn";
4901 attr_array[1] = NULL;
4902 }
4903 else if (i == 1)
4904 {
4905 strcpy(filter, "(objectClass=computer)");
4906 attr_array[0] = "cn";
4907 attr_array[1] = NULL;
4908 }
4909 else
4910 {
4911 strcpy(filter, "(objectClass=organizationalUnit)");
4912 attr_array[0] = "ou";
4913 attr_array[1] = NULL;
4914 }
4915
4916 while (1)
4917 {
4918 if ((rc = linklist_build(ldap_handle, dName, filter, attr_array,
4919 &group_base, &group_count)) != LDAP_SUCCESS)
4920 {
4921 break;
4922 }
4923 if (group_count == 0)
4924 break;
4925 pPtr = group_base;
4926 while(pPtr)
4927 {
4928 if (!strcasecmp(pPtr->attribute, "cn"))
4929 {
4930 sprintf(new_cn, "cn=%s", pPtr->value);
4931 if (i == 0)
4932 sprintf(temp, "%s,%s", orphans_other_ou, dn_path);
4933 if (i == 1)
4934 sprintf(temp, "%s,%s", orphans_machines_ou, dn_path);
4935 count = 1;
4936 while (1)
4937 {
4938 rc = ldap_rename_s(ldap_handle, pPtr->dn, new_cn, temp,
4939 TRUE, NULL, NULL);
4940 if (rc == LDAP_ALREADY_EXISTS)
4941 {
4942 sprintf(new_cn, "cn=%s_%d", pPtr->value, count);
4943 ++count;
4944 }
4945 else
4946 break;
4947 }
4948 }
4949 else if (!strcasecmp(pPtr->attribute, "ou"))
4950 {
4951 rc = ldap_delete_s(ldap_handle, pPtr->dn);
4952 }
4953 pPtr = pPtr->next;
4954 }
4955 linklist_free(group_base);
4956 group_base = NULL;
4957 group_count = 0;
4958 }
4959 }
4960 return(0);
4961}
5f7b0741 4962
4963int get_machine_ou(LDAP *ldap_handle, char *dn_path, char *member, char *machine_ou)
4964{
4965 LK_ENTRY *group_base;
4966 int group_count;
4967 int i;
4968 char filter[128];
4969 char *attr_array[3];
4970 char cn[256];
4971 char dn[256];
4972 char temp[256];
4973 char *pPtr;
3abb4456 4974 char NewMachineName[1024];
5f7b0741 4975 int rc;
4976
3abb4456 4977 strcpy(NewMachineName, member);
4978 rc = GetMachineName(NewMachineName);
4979 if (strlen(NewMachineName) == 0)
4980 {
4981 com_err(whoami, 0, "Unable to find alais for machine %s in Moira", member);
4982 return(1);
4983 }
4984
5f7b0741 4985 pPtr = NULL;
3abb4456 4986 pPtr = strchr(NewMachineName, '.');
5f7b0741 4987 if (pPtr != NULL)
4988 (*pPtr) = '\0';
4989
4990 group_base = NULL;
4991 group_count = 0;
3abb4456 4992 sprintf(filter, "(sAMAccountName=%s$)", NewMachineName);
5f7b0741 4993 attr_array[0] = "cn";
4994 attr_array[1] = NULL;
4995 sprintf(temp, "%s", dn_path);
4996 if ((rc = linklist_build(ldap_handle, temp, filter, attr_array,
4997 &group_base, &group_count)) != 0)
4998 {
4999 com_err(whoami, 0, "LDAP server couldn't process machine %s : %s",
5000 member, ldap_err2string(rc));
5001 return(1);
5002 }
5003 if (group_count != 1)
5004 {
5005 com_err(whoami, 0, "LDAP server couldn't process machine %s : machine not found in AD",
3abb4456 5006 NewMachineName);
5f7b0741 5007 return(1);
5008 }
5009 strcpy(dn, group_base->dn);
5010 strcpy(cn, group_base->value);
5011 for (i = 0; i < (int)strlen(dn); i++)
5012 dn[i] = tolower(dn[i]);
5013 for (i = 0; i < (int)strlen(cn); i++)
5014 cn[i] = tolower(cn[i]);
5015 linklist_free(group_base);
5016 pPtr = NULL;
5017 pPtr = strstr(dn, cn);
5018 if (pPtr == NULL)
5019 {
5020 com_err(whoami, 0, "LDAP server couldn't process machine %s",
5021 member);
5022 return(1);
5023 }
5024 pPtr += strlen(cn) + 1;
5025 strcpy(machine_ou, pPtr);
5026 pPtr = NULL;
5027 pPtr = strstr(machine_ou, "dc=");
5028 if (pPtr == NULL)
5029 {
5030 com_err(whoami, 0, "LDAP server couldn't process machine %s",
5031 member);
5032 return(1);
5033 }
5034 --pPtr;
5035 (*pPtr) = '\0';
5036 return(0);
5037}
bbef4f93 5038
5039int machine_move_to_ou(LDAP *ldap_handle, char * dn_path, char *MoiraMachineName, char *DestinationOu)
5040{
5041
5042 char NewCn[128];
5043 char OldDn[512];
5044 char MachineName[128];
5045 char filter[128];
5046 char *attr_array[3];
5047 char NewOu[256];
5048 char *cPtr = NULL;
5049 int group_count;
5050 long rc;
5051 LK_ENTRY *group_base;
5052
5053 group_count = 0;
5054 group_base = NULL;
5055
5056 strcpy(MachineName, MoiraMachineName);
3abb4456 5057 rc = GetMachineName(MachineName);
5058 if (strlen(MachineName) == 0)
5059 {
5060 com_err(whoami, 0, "Unable to find alais for machine %s in Moira", MoiraMachineName);
5061 return(1);
5062 }
5063
bbef4f93 5064 cPtr = strchr(MachineName, '.');
5065 if (cPtr != NULL)
5066 (*cPtr) = '\0';
5067 sprintf(filter, "(sAMAccountName=%s$)", MachineName);
5068 attr_array[0] = "sAMAccountName";
5069 attr_array[1] = NULL;
5070 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array, &group_base, &group_count)) != 0)
5071 {
5072 com_err(whoami, 0, "LDAP server couldn't process machine %s : %s",
3abb4456 5073 MoiraMachineName, ldap_err2string(rc));
bbef4f93 5074 return(1);
5075 }
5076
5077 if (group_count == 1)
5078 strcpy(OldDn, group_base->dn);
5079 linklist_free(group_base);
5080 group_base = NULL;
5081 if (group_count != 1)
5082 {
3abb4456 5083 com_err(whoami, 0, "Unable to find machine %s in AD: %s", MoiraMachineName);
bbef4f93 5084 return(1);
5085 }
5086 sprintf(NewOu, "%s,%s", DestinationOu, dn_path);
5087 cPtr = strchr(OldDn, ',');
5088 if (cPtr != NULL)
5089 {
5090 ++cPtr;
5091 if (!strcasecmp(cPtr, NewOu))
5092 return(0);
5093 }
5094 sprintf(NewCn, "CN=%s", MachineName);
5095 rc = ldap_rename_s(ldap_handle, OldDn, NewCn, NewOu, TRUE, NULL, NULL);
5096 return(rc);
5097}
5098
5099int machine_check(LDAP *ldap_handle, char *dn_path, char *machine_name)
5100{
5101 char Name[128];
5102 char *pPtr;
5103 int rc;
5104
5105 memset(Name, '\0', sizeof(Name));
5106 strcpy(Name, machine_name);
5107 pPtr = NULL;
5108 pPtr = strchr(Name, '.');
5109 if (pPtr != NULL)
5110 (*pPtr) = '\0';
5111 strcat(Name, "$");
5112 return(!(rc = checkADname(ldap_handle, dn_path, Name)));
5113}
5114
5115int machine_get_moira_container(LDAP *ldap_handle, char *dn_path, char *machine_name, char *container_name)
5116{
5117 int rc;
5118 char *av[2];
5119 char *call_args[2];
5120
5121 av[0] = machine_name;
5122 call_args[0] = (char *)container_name;
5123 rc = mr_query("get_machine_to_container_map", 1, av, machine_GetMoiraContainer,
5124 call_args);
5125 return(rc);
5126}
5127
5128int machine_GetMoiraContainer(int ac, char **av, void *ptr)
5129{
5130 char **call_args;
5131
5132 call_args = ptr;
5133 strcpy(call_args[0], av[1]);
5134 return(0);
5135}
5136
209367bd 5137int Moira_container_group_create(char **after)
5138{
5139 long rc;
5140 char GroupName[64];
c7fec834 5141 char *argv[20];
209367bd 5142
5143 memset(GroupName, '\0', sizeof(GroupName));
5144 rc = Moira_groupname_create(GroupName, after[CONTAINER_NAME],
5145 after[CONTAINER_ROWID]);
5146 if (rc)
5147 return rc;
5148
5149 argv[L_NAME] = GroupName;
5150 argv[L_ACTIVE] = "1";
5151 argv[L_PUBLIC] = "0";
5152 argv[L_HIDDEN] = "0";
5153 argv[L_MAILLIST] = "0";
5154 argv[L_GROUP] = "1";
5155 argv[L_GID] = UNIQUE_GID;
5156 argv[L_NFSGROUP] = "0";
3fe96507 5157 argv[L_MAILMAN] = "0";
5158 argv[L_MAILMAN_SERVER] = "[NONE]";
209367bd 5159 argv[L_DESC] = "auto created container group";
5160 argv[L_ACE_TYPE] = "USER";
5161 argv[L_MEMACE_TYPE] = "USER";
5162 argv[L_ACE_NAME] = "sms";
5163 argv[L_MEMACE_NAME] = "sms";
5164
3fe96507 5165 if (rc = mr_query("add_list", 15, argv, NULL, NULL))
209367bd 5166 {
5167 com_err(whoami, 0, "couldn't create container group %s for container %s: %s",
5168 GroupName, after[CONTAINER_NAME], error_message(rc));
5169 }
5170
5171 Moira_setContainerGroup(after[CONTAINER_NAME], GroupName);
5172 Moira_addGroupToParent(after[CONTAINER_NAME], GroupName);
5173
5174 return(rc);
5175}
5176
5177int Moira_container_group_update(char **before, char **after)
5178{
5179 long rc;
5180 char BeforeGroupName[64];
5181 char AfterGroupName[64];
c7fec834 5182 char *argv[20];
209367bd 5183
5184 if (!strcasecmp(after[CONTAINER_NAME], before[CONTAINER_NAME]))
5185 return(0);
5186
5187 memset(BeforeGroupName, '\0', sizeof(BeforeGroupName));
5188 Moira_getGroupName(after[CONTAINER_NAME], BeforeGroupName, 0);
5189 if (strlen(BeforeGroupName) == 0)
5190 return(0);
5191
5192 memset(AfterGroupName, '\0', sizeof(AfterGroupName));
5193 rc = Moira_groupname_create(AfterGroupName, after[CONTAINER_NAME],
5194 after[CONTAINER_ROWID]);
5195 if (rc)
5196 return rc;
5197
5198 if (strcasecmp(BeforeGroupName, AfterGroupName))
5199 {
5200 argv[L_NAME] = BeforeGroupName;
5201 argv[L_NAME + 1] = AfterGroupName;
5202 argv[L_ACTIVE + 1] = "1";
5203 argv[L_PUBLIC + 1] = "0";
5204 argv[L_HIDDEN + 1] = "1";
5205 argv[L_MAILLIST + 1] = "0";
5206 argv[L_GROUP + 1] = "1";
5207 argv[L_GID + 1] = UNIQUE_GID;
5208 argv[L_NFSGROUP + 1] = "0";
3fe96507 5209 argv[L_MAILMAN + 1] = "0";
5210 argv[L_MAILMAN_SERVER + 1] = "[NONE]";
209367bd 5211 argv[L_DESC + 1] = "auto created container group";
5212 argv[L_ACE_TYPE + 1] = "USER";
5213 argv[L_MEMACE_TYPE + 1] = "USER";
5214 argv[L_ACE_NAME + 1] = "sms";
5215 argv[L_MEMACE_NAME + 1] = "sms";
5216
3fe96507 5217 if (rc = mr_query("update_list", 16, argv, NULL, NULL))
209367bd 5218 {
5219 com_err(whoami, 0, "couldn't rename container group from %s to %s: %s",
5220 BeforeGroupName, AfterGroupName, error_message(rc));
5221 }
5222 }
5223
5224 return(rc);
5225}
5226
5227int Moira_container_group_delete(char **before)
5228{
5229 long rc = 0;
5230 char *argv[13];
5231 char GroupName[64];
5232 char ParentGroupName[64];
5233
5234 memset(ParentGroupName, '\0', sizeof(ParentGroupName));
5235 Moira_getGroupName(before[CONTAINER_NAME], ParentGroupName, 1);
5236
5237 memset(GroupName, '\0', sizeof(GroupName));
5238 if (strcmp(before[CONTAINER_GROUP_NAME], "[none]"))
5239 strcpy(GroupName, before[CONTAINER_GROUP_NAME]);
5240
5241 if ((strlen(ParentGroupName) != 0) && (strlen(GroupName) != 0))
5242 {
5243 argv[0] = ParentGroupName;
5244 argv[1] = "LIST";
5245 argv[2] = GroupName;
5246 if (rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL))
5247 {
5248 com_err(whoami, 0, "couldn't delete container group %s from list: %s",
5249 GroupName, ParentGroupName, error_message(rc));
5250 }
5251 }
5252
5253 if (strlen(GroupName) != 0)
5254 {
5255 argv[0] = GroupName;
5256 if (rc = mr_query("delete_list", 1, argv, NULL, NULL))
5257 {
5258 com_err(whoami, 0, "couldn't delete container group %s : %s",
5259 GroupName, error_message(rc));
5260 }
5261 }
5262
5263 return(rc);
5264}
5265
5266int Moira_groupname_create(char *GroupName, char *ContainerName,
5267 char *ContainerRowID)
5268{
5269 char *ptr;
5270 char *ptr1;
5271 char temp[64];
5272 char newGroupName[64];
5273 char tempGroupName[64];
5274 char *argv[1];
5275 int i;
5276 long rc;
5277
5278 strcpy(temp, ContainerName);
5279
5280 ptr1 = strrchr(temp, '/');
5281 if (ptr1 != NULL)
5282 ptr = ++ptr1;
5283 else
5284 ptr = temp;
5285
5286 if (strlen(ptr) > 25)
5287 ptr[25] ='\0';
5288
5289 sprintf(newGroupName, "cnt-%s", ptr);
5290
5291 /* change everything to lower case */
5292 ptr = newGroupName;
5293 while (*ptr)
5294 {
5295 if (isupper(*ptr))
5296 *ptr = tolower(*ptr);
5297 if (*ptr == ' ')
5298 *ptr = '-';
5299 ptr++;
5300 }
5301
5302 strcpy(tempGroupName, newGroupName);
5303 i = (int)'0';
5304 /* append 0-9 then a-z if a duplicate is found */
5305 while(1)
5306 {
5307 argv[0] = newGroupName;
5308 if (rc = mr_query("get_list_info", 1, argv, NULL, NULL))
5309 {
5310 if (rc == MR_NO_MATCH)
5311 break;
5312 com_err(whoami, 0, "Moira error while creating group name for container %s : %s",
5313 ContainerName, error_message(rc));
5314 return rc;
5315 }
5316 sprintf(newGroupName, "%s-%c", tempGroupName, i);
5317 if (i == (int)'z')
5318 {
5319 com_err(whoami, 0, "Can not find a unique group name for container %s: too many duplicate container names",
5320 ContainerName);
5321 return 1;
5322 }
5323 if (i == '9')
5324 i = 'a';
5325 else
5326 i++;
5327 }
5328
5329 strcpy(GroupName, newGroupName);
5330 return(0);
5331}
5332
5333int Moira_setContainerGroup(char *origContainerName, char *GroupName)
5334{
5335 long rc;
5336 char *argv[3];
5337
5338 argv[0] = origContainerName;
5339 argv[1] = GroupName;
5340
5341 if ((rc = mr_query("set_container_list", 2, argv, NULL, NULL)))
5342 {
5343 com_err(whoami, 0, "couldn't set container group %s in container %s: %s",
5344 GroupName, origContainerName, error_message(rc));
5345 }
5346
5347 return(0);
5348}
5349
5350 int Moira_addGroupToParent(char *origContainerName, char *GroupName)
5351 {
5352 char ContainerName[64];
5353 char ParentGroupName[64];
5354 char *argv[3];
5355 long rc;
5356
5357 strcpy(ContainerName, origContainerName);
5358
5359 Moira_getGroupName(ContainerName, ParentGroupName, 1);
5360 /* top-level container */
5361 if (strlen(ParentGroupName) == 0)
5362 return(0);
5363
5364 argv[0] = ParentGroupName;
5365 argv[1] = "LIST";
5366 argv[2] = GroupName;
5367 if ((rc = mr_query("add_member_to_list", 3, argv, NULL, NULL)))
5368 {
5369 com_err(whoami, 0, "couldn't add container group %s to parent group %s: %s",
5370 GroupName, ParentGroupName, error_message(rc));
5371 }
5372 return(0);
5373 }
5374
5375int Moira_getContainerGroup(int ac, char **av, void *ptr)
5376{
5377 char **call_args;
5378
5379 call_args = ptr;
5380 strcpy(call_args[0], av[1]);
5381 return(0);
5382}
5383
5384int Moira_getGroupName(char *origContainerName, char *GroupName,
5385 int ParentFlag)
5386{
209367bd 5387 char ContainerName[64];
5388 char *argv[3];
5389 char *call_args[3];
5390 char *ptr;
5391 long rc;
5392
5393 strcpy(ContainerName, origContainerName);
5394
5395 if (ParentFlag)
5396 {
5397 ptr = strrchr(ContainerName, '/');
5398 if (ptr != NULL)
5399 (*ptr) = '\0';
5400 else
5401 return(0);
5402 }
5403
5404 argv[0] = ContainerName;
5405 argv[1] = NULL;
5406 call_args[0] = GroupName;
5407 call_args[1] = NULL;
5408
5409 if (!(rc = mr_query("get_container_list", 1, argv, Moira_getContainerGroup,
5410 call_args)))
5411 {
5412 if (strlen(GroupName) != 0)
5413 return(0);
5414 }
5415
5416 if (rc)
5417 com_err(whoami, 0, "couldn't get container group from container %s: %s",
5418 ContainerName, error_message(rc));
5419 else
5420 com_err(whoami, 0, "couldn't get container group from container %s",
5421 ContainerName);
5422 return(0);
5423}
5424
5425int Moira_process_machine_container_group(char *MachineName, char* GroupName,
5426 int DeleteMachine)
5427{
5428 char *argv[3];
5429 long rc;
5430
5431 if (strcmp(GroupName, "[none]") == 0)
5432 return 0;
5433
5434 argv[0] = GroupName;
5435 argv[1] = "MACHINE";
5436 argv[2] = MachineName;
5437 if (!DeleteMachine)
5438 rc = mr_query("add_member_to_list", 3, argv, NULL, NULL);
5439 else
5440 rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL);
5441 if (rc)
5442 {
5443 com_err(whoami, 0, "couldn't add machine %s to container group%s: %s",
5444 MachineName, GroupName, error_message(rc));
5445 }
5446 return(0);
5447}
3abb4456 5448
5449int GetMachineName(char *MachineName)
5450{
5451 char *args[2];
5452 char NewMachineName[1024];
5453 char *szDot;
5454 int rc = 0;
5455 int i;
5456 DWORD dwLen = 0;
5457 char *call_args[2];
5458
5459 // If the address happens to be in the top-level MIT domain, great!
5460 strcpy(NewMachineName, MachineName);
5461 for (i = 0; i < (int)strlen(NewMachineName); i++)
5462 NewMachineName[i] = toupper(NewMachineName[i]);
5463 szDot = strchr(NewMachineName,'.');
5464 if ((szDot) && (!strcasecmp(szDot+1, DOMAIN_SUFFIX)))
5465 {
5466 return(0);
5467 }
5468
5469 // If not, see if it has a Moira alias in the top-level MIT domain.
5470 memset(NewMachineName, '\0', sizeof(NewMachineName));
5471 args[0] = "*";
5472 args[1] = MachineName;
5473 call_args[0] = NewMachineName;
5474 call_args[1] = NULL;
5475 if (rc = mr_query("get_hostalias", 2, args, ProcessMachineName, call_args))
5476 {
5477 com_err(whoami, 0, "couldn't resolve machine name %s : %s",
5478 MachineName, error_message(rc));
5479 strcpy(MachineName, "");
5480 return(0);
5481 }
5482
5483 if (strlen(NewMachineName) != 0)
5484 strcpy(MachineName, NewMachineName);
5485 else
5486 strcpy(MachineName, "");
5487 return(0);
5488
5489}
5490
5491int ProcessMachineName(int ac, char **av, void *ptr)
5492{
5493 char **call_args;
5494 char MachineName[1024];
5495 char *szDot;
5496 int i;
5497
5498 call_args = ptr;
5499 if (strlen(call_args[0]) == 0)
5500 {
5501 strcpy(MachineName, av[0]);
5502 for (i = 0; i < (int)strlen(MachineName); i++)
5503 MachineName[i] = toupper(MachineName[i]);
5504 szDot = strchr(MachineName,'.');
5505 if ((szDot) && (!strcasecmp(szDot+1,DOMAIN_SUFFIX)))
5506 {
5507 strcpy(call_args[0], MachineName);
5508 }
5509 }
5510 return(0);
5511}
5512
5513void SwitchSFU(LDAPMod **mods, int *UseSFU30, int n)
5514{
5515 int i;
5516
5517 if (*UseSFU30)
5518 {
5519 for (i = 0; i < n; i++)
5520 {
5521 if (!strcmp(mods[i]->mod_type, "msSFU30UidNumber"))
5522 mods[i]->mod_type = "uidNumber";
5523 }
5524 (*UseSFU30) = 0;
5525 }
5526 else
5527 {
5528 for (i = 0; i < n; i++)
5529 {
5530 if (!strcmp(mods[i]->mod_type, "uidNumber"))
5531 mods[i]->mod_type = "msSFU30UidNumber";
5532 }
5533 (*UseSFU30) = 1;
5534 }
5535}
5536
5537int SetHomeDirectory(LDAP *ldap_handle, char *user_name, char *DistinguishedName,
5538 char *WinHomeDir, char *WinProfileDir,
5539 char **homedir_v, char **winProfile_v,
5540 char **drives_v, LDAPMod **mods,
5541 int OpType, int n)
5542{
5543 char **hp;
5544 char cWeight[3];
5545 char cPath[1024];
5546 char path[1024];
5547 char winPath[1024];
5548 char winProfile[1024];
5549 char homeDrive[8];
5550 int last_weight;
5551 int i;
5552 int rc;
5553 LDAPMod *DelMods[20];
5554
5555 memset(homeDrive, '\0', sizeof(homeDrive));
5556 memset(path, '\0', sizeof(path));
5557 memset(winPath, '\0', sizeof(winPath));
5558 memset(winProfile, '\0', sizeof(winProfile));
5559 hp = NULL;
5560 if ((!strcasecmp(WinHomeDir, "[afs]")) || (!strcasecmp(WinProfileDir, "[afs]")))
5561 {
5562 if ((hp = hes_resolve(user_name, "filsys")) != NULL)
5563 {
5564 memset(cWeight, 0, sizeof(cWeight));
5565 memset(cPath, 0, sizeof(cPath));
5566 last_weight = 1000;
5567 i = 0;
5568 while (hp[i] != NULL)
5569 {
5570 if (sscanf(hp[i], "%*s %s", cPath))
5571 {
5572 if (strnicmp(cPath, AFS, strlen(AFS)) == 0)
5573 {
5574 if (sscanf(hp[i], "%*s %*s %*s %*s %s", cWeight))
5575 {
5576 if (atoi(cWeight) < last_weight)
5577 {
5578 strcpy(path, cPath);
5579 last_weight = (int)atoi(cWeight);
5580 }
5581 }
5582 else
5583 strcpy(path, cPath);
5584 }
5585 }
5586 ++i;
5587 }
5588 if (strlen(path))
5589 {
5590 if (!strnicmp(path, AFS, strlen(AFS)))
5591 {
5592 AfsToWinAfs(path, winPath);
5593 strcpy(winProfile, winPath);
5594 strcat(winProfile, "\\.winprofile");
5595 }
5596 }
5597 }
5598 }
5599
5600 if (hp != NULL)
5601 {
5602 i = 0;
5603 while (hp[i])
5604 {
5605 free(hp[i]);
5606 i++;
5607 }
5608 }
5609
5610 if (!strcasecmp(WinHomeDir, "[local]"))
5611 memset(winPath, '\0', sizeof(winPath));
5612 else if (!strcasecmp(WinHomeDir, "[afs]"))
5613 {
5614 strcpy(homeDrive, "H:");
5615 }
5616 else
5617 {
5618 strcpy(winPath, WinHomeDir);
5619 if (!strncmp(WinHomeDir, "\\\\", 2))
5620 {
5621 strcpy(homeDrive, "H:");
5622 }
5623 }
5624
5625 // nothing needs to be done if WinProfileDir is [afs].
5626 if (!strcasecmp(WinProfileDir, "[local]"))
5627 memset(winProfile, '\0', sizeof(winProfile));
5628 else if (strcasecmp(WinProfileDir, "[afs]"))
5629 {
5630 strcpy(winProfile, WinProfileDir);
5631 }
5632
5633 if (strlen(winProfile) != 0)
5634 {
5635 if (winProfile[strlen(winProfile) - 1] == '\\')
5636 winProfile[strlen(winProfile) - 1] = '\0';
5637 }
5638 if (strlen(winPath) != 0)
5639 {
5640 if (winPath[strlen(winPath) - 1] == '\\')
5641 winPath[strlen(winPath) - 1] = '\0';
5642 }
5643
5644 if ((winProfile[1] == ':') && (strlen(winProfile) == 2))
5645 strcat(winProfile, "\\");
5646 if ((winPath[1] == ':') && (strlen(winPath) == 2))
5647 strcat(winPath, "\\");
5648
5649 if (strlen(winPath) == 0)
5650 {
5651 if (OpType == LDAP_MOD_REPLACE)
5652 {
5653 i = 0;
5654 DEL_ATTR("homeDirectory", LDAP_MOD_DELETE);
5655 DelMods[i] = NULL;
5656 //unset homeDirectory attribute for user.
5657 rc = ldap_modify_s(ldap_handle, DistinguishedName, DelMods);
5658 free(DelMods[0]);
5659 }
5660 }
5661 else
5662 {
5663 homedir_v[0] = strdup(winPath);
5664 ADD_ATTR("homeDirectory", homedir_v, OpType);
5665 }
5666
5667 if (strlen(winProfile) == 0)
5668 {
5669 if (OpType == LDAP_MOD_REPLACE)
5670 {
5671 i = 0;
5672 DEL_ATTR("profilePath", LDAP_MOD_DELETE);
5673 DelMods[i] = NULL;
5674 //unset profilePate attribute for user.
5675 rc = ldap_modify_s(ldap_handle, DistinguishedName, DelMods);
5676 free(DelMods[0]);
5677 }
5678 }
5679 else
5680 {
5681 winProfile_v[0] = strdup(winProfile);
5682 ADD_ATTR("profilePath", winProfile_v, OpType);
5683 }
5684
5685 if (strlen(homeDrive) == 0)
5686 {
5687 if (OpType == LDAP_MOD_REPLACE)
5688 {
5689 i = 0;
5690 DEL_ATTR("homeDrive", LDAP_MOD_DELETE);
5691 DelMods[i] = NULL;
5692 //unset homeDrive attribute for user
5693 rc = ldap_modify_s(ldap_handle, DistinguishedName, DelMods);
5694 free(DelMods[0]);
5695 }
5696 }
5697 else
5698 {
5699 drives_v[0] = strdup(homeDrive);
5700 ADD_ATTR("homeDrive", drives_v, OpType);
5701 }
5702
5703 return(n);
5704}
This page took 0.989833 seconds and 5 git commands to generate.