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