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