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