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