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