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