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