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