]>
Commit | Line | Data |
---|---|---|
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 |
9 | * users 11 11 username 45206 /bin/cmd cmd Last First Middle 2 950000001 STAFF 121058 username 45206 /bin/cmd cmd Last First Middle 1 950000001 STAFF 121058 | |
10 | * users 11 11 #45206 45206 /bin/cmd cmd Last First Middle 0 950000001 STAFF 121058 newuser 45206 /bin/cmd cmd Last First Middle 2 950000001 STAFF 121058 | |
11 | * login, unix_uid, shell, winconsoleshell, last, first, middle, status, mitid, type, moiraid | |
78af4e6e | 12 | * |
89db421e | 13 | * arguments for deactivating/deleting a user account |
14 | * users 11 11 username 45206 /bin/cmd cmd Last First Middle 1 950000001 STAFF 121058 username 45206 /bin/cmd cmd Last First Middle 3 950000001 STAFF 121058 | |
15 | * users 11 11 username 45206 /bin/cmd cmd Last First Middle 2 950000001 STAFF 121058 username 45206 /bin/cmd cmd Last First Middle 3 950000001 STAFF 121058 | |
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 |
24 | * users 11 11 oldusername 45206 /bin/cmd cmd Last First Middle 1 950000001 STAFF 121058 newusername 45206 /bin/cmd cmd Last First Middle 1 950000001 STAFF 121058 | |
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). | |
84 | * containers 0 7 machines/test/bottom description location contact USER 105316 2222 | |
85 | * | |
86 | * arguments when moira deletes a container (OU). | |
87 | * containers 7 0 machines/test/bottom description location contact USER 105316 2222 | |
88 | * | |
89 | * arguments when moira modifies a container information (OU). | |
90 | * containers 7 7 machines/test/bottom description location contact USER 105316 2222 machines/test/bottom description1 location contact USER 10531 2222 | |
cd9e6b16 | 91 | */ |
5d0a7127 | 92 | #include <mit-copyright.h> |
93 | #ifdef _WIN32 | |
94 | #include <windows.h> | |
95 | #include <stdlib.h> | |
96 | #include <malloc.h> | |
97 | #include <lmaccess.h> | |
98 | #endif | |
f78c7eaf | 99 | #include <hesiod.h> |
cd9e6b16 | 100 | #include <string.h> |
5d0a7127 | 101 | #include <ldap.h> |
102 | #include <stdio.h> | |
103 | #include <moira.h> | |
104 | #include <moira_site.h> | |
cd9e6b16 | 105 | #include <mrclient.h> |
5d0a7127 | 106 | #include <krb5.h> |
107 | #include <krb.h> | |
108 | #include <gsssasl.h> | |
109 | #include <gssldap.h> | |
cd9e6b16 | 110 | #include "kpasswd.h" |
111 | ||
112 | #ifdef _WIN32 | |
113 | #ifndef ECONNABORTED | |
114 | #define ECONNABORTED WSAECONNABORTED | |
115 | #endif | |
116 | #ifndef ECONNREFUSED | |
117 | #define ECONNREFUSED WSAECONNREFUSED | |
118 | #endif | |
119 | #ifndef EHOSTUNREACH | |
120 | #define EHOSTUNREACH WSAEHOSTUNREACH | |
121 | #endif | |
122 | #define krb5_xfree free | |
0d958b3c | 123 | #define F_OK 0 |
124 | #define sleep(A) Sleep(A * 1000); | |
cd9e6b16 | 125 | #endif /* _WIN32 */ |
5d0a7127 | 126 | |
127 | #ifndef _WIN32 | |
f78c7eaf | 128 | #include <sys/types.h> |
129 | #include <netinet/in.h> | |
130 | #include <arpa/nameser.h> | |
131 | #include <resolv.h> | |
5d0a7127 | 132 | #include <sys/utsname.h> |
0d958b3c | 133 | #include <unistd.h> |
5d0a7127 | 134 | |
f75f605a | 135 | #define WINADCFG "/moira/winad/winad.cfg" |
f78c7eaf | 136 | #define strnicmp(A,B,C) strncasecmp(A,B,C) |
cd9e6b16 | 137 | #define UCHAR unsigned char |
138 | ||
5d0a7127 | 139 | #define UF_SCRIPT 0x0001 |
140 | #define UF_ACCOUNTDISABLE 0x0002 | |
141 | #define UF_HOMEDIR_REQUIRED 0x0008 | |
142 | #define UF_LOCKOUT 0x0010 | |
143 | #define UF_PASSWD_NOTREQD 0x0020 | |
144 | #define UF_PASSWD_CANT_CHANGE 0x0040 | |
cd9e6b16 | 145 | #define UF_DONT_EXPIRE_PASSWD 0x10000 |
5d0a7127 | 146 | |
147 | #define UF_TEMP_DUPLICATE_ACCOUNT 0x0100 | |
148 | #define UF_NORMAL_ACCOUNT 0x0200 | |
149 | #define UF_INTERDOMAIN_TRUST_ACCOUNT 0x0800 | |
150 | #define UF_WORKSTATION_TRUST_ACCOUNT 0x1000 | |
151 | #define UF_SERVER_TRUST_ACCOUNT 0x2000 | |
152 | ||
153 | #ifndef BYTE | |
154 | #define BYTE unsigned char | |
155 | #endif | |
156 | typedef unsigned int DWORD; | |
157 | typedef unsigned long ULONG; | |
158 | ||
159 | typedef struct _GUID | |
160 | { | |
161 | unsigned long Data1; | |
162 | unsigned short Data2; | |
163 | unsigned short Data3; | |
164 | unsigned char Data4[8]; | |
165 | } GUID; | |
166 | ||
167 | typedef struct _SID_IDENTIFIER_AUTHORITY { | |
168 | BYTE Value[6]; | |
169 | } SID_IDENTIFIER_AUTHORITY, *PSID_IDENTIFIER_AUTHORITY; | |
170 | ||
171 | typedef struct _SID { | |
172 | BYTE Revision; | |
173 | BYTE SubAuthorityCount; | |
174 | SID_IDENTIFIER_AUTHORITY IdentifierAuthority; | |
175 | DWORD SubAuthority[512]; | |
176 | } SID; | |
177 | #endif/*!WIN32*/ | |
178 | ||
f75f605a | 179 | #ifndef WINADCFG |
180 | #define WINADCFG "winad.cfg" | |
181 | #endif | |
182 | ||
f78c7eaf | 183 | #define AFS "/afs/" |
184 | #define WINAFS "\\\\afs\\all\\" | |
185 | ||
cd9e6b16 | 186 | #define ADS_GROUP_TYPE_GLOBAL_GROUP 0x00000002 |
f78c7eaf | 187 | #define ADS_GROUP_TYPE_DOMAIN_LOCAL_GROUP 0x00000004 |
188 | #define ADS_GROUP_TYPE_LOCAL_GROUP 0x00000004 | |
189 | #define ADS_GROUP_TYPE_UNIVERSAL_GROUP 0x00000008 | |
190 | #define ADS_GROUP_TYPE_SECURITY_ENABLED 0x80000000 | |
cd9e6b16 | 191 | |
192 | #define QUERY_VERSION -1 | |
193 | #define PRIMARY_REALM "ATHENA.MIT.EDU" | |
194 | ||
5d0a7127 | 195 | #define SUBSTITUTE 1 |
196 | #define REPLACE 2 | |
197 | ||
cd9e6b16 | 198 | #define USERS 0 |
199 | #define GROUPS 1 | |
200 | ||
5d0a7127 | 201 | #define MEMBER_ADD 1 |
202 | #define MEMBER_REMOVE 2 | |
203 | #define MEMBER_CHANGE_NAME 3 | |
204 | #define MEMBER_ACTIVATE 4 | |
205 | #define MEMBER_DEACTIVATE 5 | |
cd9e6b16 | 206 | #define MEMBER_CREATE 6 |
5d0a7127 | 207 | |
f78c7eaf | 208 | #define MOIRA_ALL 0x0 |
209 | #define MOIRA_USERS 0x1 | |
210 | #define MOIRA_KERBEROS 0x2 | |
211 | #define MOIRA_STRINGS 0x4 | |
212 | #define MOIRA_LISTS 0x8 | |
213 | ||
89db421e | 214 | #define CHECK_GROUPS 1 |
215 | #define CLEANUP_GROUPS 2 | |
216 | ||
217 | #define AD_NO_GROUPS_FOUND -1 | |
218 | #define AD_WRONG_GROUP_DN_FOUND -2 | |
219 | #define AD_MULTIPLE_GROUPS_FOUND -3 | |
220 | #define AD_INVALID_NAME -4 | |
221 | #define AD_LDAP_FAILURE -5 | |
222 | #define AD_INVALID_FILESYS -6 | |
223 | #define AD_NO_ATTRIBUTE_FOUND -7 | |
224 | #define AD_NO_OU_FOUND -8 | |
225 | #define AD_NO_USER_FOUND -9 | |
226 | ||
6c8f12af | 227 | /* container arguments */ |
228 | #define CONTAINER_NAME 0 | |
229 | #define CONTAINER_DESC 1 | |
230 | #define CONTAINER_LOCATION 2 | |
231 | #define CONTAINER_CONTACT 3 | |
232 | #define CONTAINER_TYPE 4 | |
233 | #define CONTAINER_ID 5 | |
234 | #define CONTAINER_ROWID 6 | |
235 | ||
5d0a7127 | 236 | typedef struct lk_entry { |
237 | int op; | |
238 | int length; | |
239 | int ber_value; | |
240 | char *dn; | |
241 | char *attribute; | |
242 | char *value; | |
243 | char *member; | |
244 | char *type; | |
245 | char *list; | |
246 | struct lk_entry *next; | |
247 | } LK_ENTRY; | |
248 | ||
0d958b3c | 249 | #define STOP_FILE "/moira/winad/nowinad" |
250 | #define file_exists(file) (access((file), F_OK) == 0) | |
251 | ||
5d0a7127 | 252 | #define LDAP_BERVAL struct berval |
cd9e6b16 | 253 | #define MAX_SERVER_NAMES 32 |
254 | ||
255 | #define ADD_ATTR(t, v, o) \ | |
256 | mods[n] = malloc(sizeof(LDAPMod)); \ | |
257 | mods[n]->mod_op = o; \ | |
258 | mods[n]->mod_type = t; \ | |
259 | mods[n++]->mod_values = v | |
5d0a7127 | 260 | |
261 | LK_ENTRY *member_base = NULL; | |
cd9e6b16 | 262 | LK_ENTRY *sid_base = NULL; |
263 | LK_ENTRY **sid_ptr = NULL; | |
0d958b3c | 264 | static char tbl_buf[1024]; |
89db421e | 265 | char kerberos_ou[] = "OU=kerberos,OU=moira"; |
266 | char contact_ou[] = "OU=strings,OU=moira"; | |
267 | char user_ou[] = "OU=users,OU=moira"; | |
268 | char group_ou_distribution[] = "OU=mail,OU=lists,OU=moira"; | |
269 | char group_ou_root[] = "OU=lists,OU=moira"; | |
270 | char group_ou_security[] = "OU=group,OU=lists,OU=moira"; | |
271 | char group_ou_neither[] = "OU=special,OU=lists,OU=moira"; | |
272 | char group_ou_both[] = "OU=mail,OU=group,OU=lists,OU=moira"; | |
6c8f12af | 273 | char orphans_machines_ou[] = "OU=Machines,OU=Orphans"; |
274 | char orphans_other_ou[] = "OU=Other,OU=Orphans"; | |
5d0a7127 | 275 | char *whoami; |
cd9e6b16 | 276 | char ldap_domain[256]; |
cd9e6b16 | 277 | int mr_connections = 0; |
78af4e6e | 278 | int callback_rc; |
f78c7eaf | 279 | char default_server[256]; |
bfb6f0ad | 280 | static char tbl_buf[1024]; |
cd9e6b16 | 281 | |
f78c7eaf | 282 | extern int set_password(char *user, char *password, char *domain); |
cd9e6b16 | 283 | |
89db421e | 284 | int ad_get_group(LDAP *ldap_handle, char *dn_path, char *group_name, |
285 | char *group_membership, char *MoiraId, char *attribute, | |
286 | LK_ENTRY **linklist_base, int *linklist_count, | |
287 | char *rFilter); | |
f78c7eaf | 288 | void AfsToWinAfs(char* path, char* winPath); |
289 | int ad_connect(LDAP **ldap_handle, char *ldap_domain, char *dn_path, | |
290 | char *Win2kPassword, char *Win2kUser, char *default_server, | |
291 | int connect_to_kdc); | |
292 | void ad_kdc_disconnect(); | |
0d958b3c | 293 | void check_winad(void); |
89db421e | 294 | int check_user(LDAP *ldap_handle, char *dn_path, char *UserName, char *MoiraId); |
6c8f12af | 295 | /* containers */ |
296 | int container_adupdate(LDAP *ldap_handle, char *dn_path, char *dName, | |
297 | char *distinguishedName, int count, char **av); | |
298 | void container_check(LDAP *ldap_handle, char *dn_path, char *name); | |
299 | int container_create(LDAP *ldap_handle, char *dn_path, int count, char **av); | |
300 | int container_delete(LDAP *ldap_handle, char *dn_path, int count, char **av); | |
301 | int container_get_distinguishedName(LDAP *ldap_handle, char *dn_path, | |
302 | char *distinguishedName, int count, char **av); | |
303 | void container_get_dn(char *src, char *dest); | |
304 | void container_get_name(char *src, char *dest); | |
305 | int container_move_objects(LDAP *ldap_handle, char *dn_path, char *dName); | |
306 | int container_rename(LDAP *ldap_handle, char *dn_path, int beforec, char **before, | |
307 | int afterc, char **after); | |
308 | int container_update(LDAP *ldap_handle, char *dn_path, int beforec, char **before, | |
309 | int afterc, char **after); | |
310 | ||
f75f605a | 311 | int filesys_process(LDAP *ldap_handle, char *dn_path, char *fs_name, |
312 | char *fs_type, char *fs_pack, int operation); | |
313 | int get_group_membership(char *group_membership, char *group_ou, | |
314 | int *security_flag, char **av); | |
89db421e | 315 | int process_group(LDAP *ldap_handle, char *dn_path, char *MoiraId, |
316 | char *group_name, char *group_ou, char *group_membership, | |
317 | int group_security_flag, int type); | |
f75f605a | 318 | int process_lists(int ac, char **av, void *ptr); |
cd9e6b16 | 319 | int user_create(int ac, char **av, void *ptr); |
89db421e | 320 | int user_change_status(LDAP *ldap_handle, char *dn_path, |
321 | char *user_name, char *MoiraId, int operation); | |
322 | int user_delete(LDAP *ldap_handle, char *dn_path, | |
323 | char *u_name, char *MoiraId); | |
f75f605a | 324 | int user_rename(LDAP *ldap_handle, char *dn_path, char *before_user_name, |
89db421e | 325 | char *user_name); |
f75f605a | 326 | int user_update(LDAP *ldap_handle, char *dn_path, char *user_name, |
89db421e | 327 | char *uid, char *MitId, char *MoiraId, int State); |
328 | void change_to_lower_case(char *ptr); | |
cd9e6b16 | 329 | int contact_create(LDAP *ld, char *bind_path, char *user, char *group_ou); |
cd9e6b16 | 330 | int group_create(int ac, char **av, void *ptr); |
f75f605a | 331 | int group_delete(LDAP *ldap_handle, char *dn_path, |
89db421e | 332 | char *group_name, char *group_membership, char *MoiraId); |
f75f605a | 333 | int group_rename(LDAP *ldap_handle, char *dn_path, |
334 | char *before_group_name, char *before_group_membership, | |
5a775f54 | 335 | char *before_group_ou, int before_security_flag, char *before_desc, |
f75f605a | 336 | char *after_group_name, char *after_group_membership, |
89db421e | 337 | char *after_group_ou, int after_security_flag, char *after_desc, |
338 | char *MoiraId, char *filter); | |
339 | int make_new_group(LDAP *ldap_handle, char *dn_path, char *MoiraId, | |
340 | char *group_name, char *group_ou, char *group_membership, | |
341 | int group_security_flag, int updateGroup); | |
cd9e6b16 | 342 | int member_list_build(int ac, char **av, void *ptr); |
f75f605a | 343 | int member_add(LDAP *ldap_handle, char *dn_path, char *group_name, |
344 | char *group_ou, char *group_membership, | |
89db421e | 345 | char *user_name, char *pUserOu, char *MoiraId); |
78af4e6e | 346 | int member_remove(LDAP *ldap_handle, char *dn_path, char *group_name, |
f75f605a | 347 | char *group_ou, char *group_membership, char *user_name, |
89db421e | 348 | char *pUserOu, char *MoiraId); |
349 | int populate_group(LDAP *ldap_handle, char *dn_path, char *group_name, | |
350 | char *group_ou, char *group_membership, | |
351 | int group_security_flag, char *MoiraId); | |
cd9e6b16 | 352 | int sid_update(LDAP *ldap_handle, char *dn_path); |
353 | int check_string(char *s); | |
354 | void convert_b_to_a(char *string, UCHAR *binary, int length); | |
355 | int mr_connect_cl(char *server, char *client, int version, int auth); | |
356 | ||
6c8f12af | 357 | void do_container(LDAP *ldap_handle, char *dn_path, char *ldap_hostname, |
358 | char **before, int beforec, char **after, int afterc); | |
f78c7eaf | 359 | void do_filesys(LDAP *ldap_handle, char *dn_path, char *ldap_hostname, |
360 | char **before, int beforec, char **after, int afterc); | |
361 | void do_list(LDAP *ldap_handle, char *dn_path, char *ldap_hostname, | |
362 | char **before, int beforec, char **after, int afterc); | |
363 | void do_user(LDAP *ldap_handle, char *dn_path, char *ldap_hostname, | |
cd9e6b16 | 364 | char **before, int beforec, char **after, int afterc); |
5d0a7127 | 365 | void do_member(LDAP *ldap_handle, char *dn_path, char *ldap_hostname, |
cd9e6b16 | 366 | char **before, int beforec, char **after, int afterc); |
367 | int linklist_create_entry(char *attribute, char *value, | |
368 | LK_ENTRY **linklist_entry); | |
5d0a7127 | 369 | int linklist_build(LDAP *ldap_handle, char *dn_path, char *search_exp, |
cd9e6b16 | 370 | char **attr_array, LK_ENTRY **linklist_base, |
371 | int *linklist_count); | |
5d0a7127 | 372 | void linklist_free(LK_ENTRY *linklist_base); |
cd9e6b16 | 373 | |
374 | int retrieve_attributes(LDAP *ldap_handle, LDAPMessage *ldap_entry, | |
375 | char *distinguished_name, LK_ENTRY **linklist_current); | |
376 | int retrieve_entries(LDAP *ldap_handle, LDAPMessage *ldap_entry, | |
377 | LK_ENTRY **linklist_base, int *linklist_count); | |
378 | int retrieve_values(LDAP *ldap_handle, LDAPMessage *ldap_entry, | |
379 | char *Attribute, char *distinguished_name, | |
380 | LK_ENTRY **linklist_current); | |
381 | ||
382 | int construct_newvalues(LK_ENTRY *linklist_base, int modvalue_count, | |
383 | char *oldValue, char *newValue, | |
384 | char ***modvalues, int type); | |
385 | void free_values(char **modvalues); | |
386 | ||
387 | int convert_domain_to_dn(char *domain, char **bind_path); | |
5d0a7127 | 388 | void get_distinguished_name(LDAP *ldap_handle, LDAPMessage *ldap_entry, |
cd9e6b16 | 389 | char *distinguished_name); |
5d0a7127 | 390 | int moira_disconnect(void); |
391 | int moira_connect(void); | |
392 | void print_to_screen(const char *fmt, ...); | |
5d0a7127 | 393 | |
394 | int main(int argc, char **argv) | |
395 | { | |
cd9e6b16 | 396 | unsigned long rc; |
397 | int beforec; | |
398 | int afterc; | |
cd9e6b16 | 399 | int i; |
cd9e6b16 | 400 | char *table; |
401 | char **before; | |
402 | char **after; | |
cd9e6b16 | 403 | LDAP *ldap_handle; |
5d0a7127 | 404 | FILE *fptr; |
f78c7eaf | 405 | char dn_path[256]; |
cd9e6b16 | 406 | |
5d0a7127 | 407 | whoami = ((whoami = (char *)strrchr(argv[0], '/')) ? whoami+1 : argv[0]); |
cd9e6b16 | 408 | |
409 | if (argc < 4) | |
410 | { | |
411 | com_err(whoami, 0, "%s", "argc < 4"); | |
412 | exit(1); | |
413 | } | |
414 | beforec = atoi(argv[2]); | |
415 | afterc = atoi(argv[3]); | |
416 | ||
417 | if (argc < (4 + beforec + afterc)) | |
418 | { | |
419 | com_err(whoami, 0, "%s", "argc < (4 + breforec + afterc)"); | |
420 | exit(1); | |
421 | } | |
422 | ||
423 | table = argv[1]; | |
424 | before = &argv[4]; | |
425 | after = &argv[4 + beforec]; | |
426 | ||
bfb6f0ad | 427 | for (i = 1; i < argc; i++) |
0d958b3c | 428 | { |
bfb6f0ad | 429 | strcat(tbl_buf, argv[i]); |
430 | strcat(tbl_buf, " "); | |
0d958b3c | 431 | } |
bfb6f0ad | 432 | com_err(whoami, 0, "%s", tbl_buf); |
433 | ||
0d958b3c | 434 | check_winad(); |
f75f605a | 435 | |
cd9e6b16 | 436 | memset(ldap_domain, '\0', sizeof(ldap_domain)); |
f75f605a | 437 | if ((fptr = fopen(WINADCFG, "r")) != NULL) |
5d0a7127 | 438 | { |
cd9e6b16 | 439 | fread(ldap_domain, sizeof(char), sizeof(ldap_domain), fptr); |
5d0a7127 | 440 | fclose(fptr); |
441 | } | |
cd9e6b16 | 442 | if (strlen(ldap_domain) == 0) |
9db0b148 | 443 | strcpy(ldap_domain, "win.mit.edu"); |
5d0a7127 | 444 | initialize_sms_error_table(); |
445 | initialize_krb_error_table(); | |
cd9e6b16 | 446 | |
f78c7eaf | 447 | memset(default_server, '\0', sizeof(default_server)); |
448 | memset(dn_path, '\0', sizeof(dn_path)); | |
89db421e | 449 | for (i = 0; i < 5; i++) |
cd9e6b16 | 450 | { |
89db421e | 451 | if (!(rc = ad_connect(&ldap_handle, ldap_domain, dn_path, "", "", default_server, 1))) |
452 | break; | |
453 | sleep(2); | |
454 | } | |
455 | if (rc) | |
456 | { | |
457 | critical_alert("incremental", "winad.incr cannot connect to any server in domain %s", ldap_domain); | |
cd9e6b16 | 458 | exit(1); |
459 | } | |
cd9e6b16 | 460 | |
9db0b148 | 461 | for (i = 0; i < (int)strlen(table); i++) |
462 | table[i] = tolower(table[i]); | |
5d0a7127 | 463 | if (!strcmp(table, "users")) |
f78c7eaf | 464 | do_user(ldap_handle, dn_path, ldap_domain, before, beforec, after, |
465 | afterc); | |
5d0a7127 | 466 | else if (!strcmp(table, "list")) |
cd9e6b16 | 467 | do_list(ldap_handle, dn_path, ldap_domain, before, beforec, after, |
468 | afterc); | |
5d0a7127 | 469 | else if (!strcmp(table, "imembers")) |
cd9e6b16 | 470 | do_member(ldap_handle, dn_path, ldap_domain, before, beforec, after, |
471 | afterc); | |
cd9e6b16 | 472 | else if (!strcmp(table, "filesys")) |
f78c7eaf | 473 | do_filesys(ldap_handle, dn_path, ldap_domain, before, beforec, after, |
474 | afterc); | |
6c8f12af | 475 | else if (!strcmp(table, "containers")) |
476 | do_container(ldap_handle, dn_path, ldap_domain, before, beforec, after, | |
477 | afterc); | |
f78c7eaf | 478 | ad_kdc_disconnect(); |
5d0a7127 | 479 | rc = ldap_unbind_s(ldap_handle); |
5d0a7127 | 480 | exit(0); |
481 | } | |
482 | ||
6c8f12af | 483 | void do_container(LDAP *ldap_handle, char *dn_path, char *ldap_hostname, |
484 | char **before, int beforec, char **after, int afterc) | |
485 | { | |
486 | ||
487 | if ((beforec == 0) && (afterc == 0)) | |
488 | return; | |
489 | ||
490 | if ((beforec != 0) && (afterc == 0)) /*delete a new container*/ | |
491 | { | |
492 | com_err(whoami, 0, "deleting container %s", before[CONTAINER_NAME]); | |
493 | container_delete(ldap_handle, dn_path, beforec, before); | |
494 | return; | |
495 | } | |
496 | if ((beforec == 0) && (afterc != 0)) /*create a container*/ | |
497 | { | |
498 | com_err(whoami, 0, "creating container %s", before[CONTAINER_NAME]); | |
499 | container_check(ldap_handle, dn_path, after[CONTAINER_NAME]); | |
500 | container_create(ldap_handle, dn_path, afterc, after); | |
501 | return; | |
502 | } | |
503 | ||
504 | if (strcasecmp(before[CONTAINER_NAME], after[CONTAINER_NAME])) | |
505 | { | |
506 | com_err(whoami, 0, "renaming container %s to %s", before[CONTAINER_NAME], after[CONTAINER_NAME]); | |
507 | container_rename(ldap_handle, dn_path, beforec, before, afterc, after); | |
508 | return; | |
509 | } | |
510 | container_update(ldap_handle, dn_path, beforec, before, afterc, after); | |
511 | return; | |
512 | } | |
513 | ||
f78c7eaf | 514 | void do_filesys(LDAP *ldap_handle, char *dn_path, char *ldap_hostname, |
515 | char **before, int beforec, char **after, int afterc) | |
516 | { | |
517 | long rc; | |
518 | char *av[3]; | |
519 | char *call_args[7]; | |
520 | int acreate; | |
521 | int atype; | |
522 | int bcreate; | |
523 | int btype; | |
f75f605a | 524 | int abort_flag; |
f78c7eaf | 525 | |
f75f605a | 526 | abort_flag = 0; |
f78c7eaf | 527 | |
528 | if (afterc < FS_CREATE) | |
529 | atype = acreate = 0; | |
530 | else | |
531 | { | |
532 | atype = !strcmp(after[FS_TYPE], "AFS"); | |
533 | acreate = atoi(after[FS_CREATE]); | |
534 | } | |
535 | ||
536 | if (beforec < FS_CREATE) | |
537 | { | |
538 | if (acreate == 0 || atype == 0) | |
539 | goto cleanup; | |
540 | com_err(whoami, 0, "Processing filesys %s", after[FS_NAME]); | |
f75f605a | 541 | abort_flag = 0; |
542 | while (1) | |
543 | { | |
544 | if ((rc = filesys_process(ldap_handle, dn_path, after[FS_NAME], | |
545 | after[FS_TYPE], after[FS_PACK], LDAP_MOD_ADD)) != LDAP_NO_SUCH_OBJECT) | |
546 | { | |
547 | if (rc != LDAP_SUCCESS) | |
548 | com_err(whoami, 0, "Couldn't process filesys %s", after[FS_NAME]); | |
549 | break; | |
550 | } | |
551 | if (abort_flag == 1) | |
552 | break; | |
553 | sleep(1); | |
554 | abort_flag = 1; | |
555 | if (rc = moira_connect()) | |
556 | { | |
557 | critical_alert("AD incremental", | |
558 | "Error contacting Moira server : %s", | |
559 | error_message(rc)); | |
560 | return; | |
561 | } | |
562 | av[0] = after[FS_NAME]; | |
563 | call_args[0] = (char *)ldap_handle; | |
564 | call_args[1] = dn_path; | |
89db421e | 565 | call_args[2] = ""; |
f75f605a | 566 | call_args[3] = NULL; |
567 | sid_base = NULL; | |
568 | sid_ptr = &sid_base; | |
5b8457c5 | 569 | callback_rc = 0; |
f75f605a | 570 | if (rc = mr_query("get_user_account_by_login", 1, av, user_create, |
571 | call_args)) | |
572 | { | |
573 | moira_disconnect(); | |
574 | com_err(whoami, 0, "Couldn't process filesys %s", after[FS_NAME]); | |
575 | break; | |
576 | } | |
5b8457c5 | 577 | if (callback_rc) |
578 | { | |
579 | moira_disconnect(); | |
580 | com_err(whoami, 0, "Couldn't process filesys %s", after[FS_NAME]); | |
581 | break; | |
582 | } | |
f75f605a | 583 | if (sid_base != NULL) |
584 | { | |
585 | sid_update(ldap_handle, dn_path); | |
586 | linklist_free(sid_base); | |
587 | sid_base = NULL; | |
588 | } | |
589 | moira_disconnect(); | |
590 | } | |
f78c7eaf | 591 | goto cleanup; |
592 | } | |
593 | ||
594 | btype = !strcmp(before[FS_TYPE], "AFS"); | |
595 | bcreate = atoi(before[FS_CREATE]); | |
596 | if (afterc < FS_CREATE) | |
597 | { | |
598 | if (btype && bcreate) | |
599 | { | |
f75f605a | 600 | if (rc = filesys_process(ldap_handle, dn_path, before[FS_NAME], |
601 | before[FS_TYPE], before[FS_PACK], LDAP_MOD_DELETE)) | |
f78c7eaf | 602 | { |
f75f605a | 603 | com_err(whoami, 0, "Couldn't delete filesys %s", before[FS_NAME]); |
f78c7eaf | 604 | } |
605 | } | |
f75f605a | 606 | return; |
f78c7eaf | 607 | } |
608 | ||
609 | if (!acreate) | |
f75f605a | 610 | return; |
f78c7eaf | 611 | |
612 | if (!atype && !btype) | |
613 | { | |
614 | if (strcmp(before[FS_TYPE], "ERR") || strcmp(after[FS_TYPE], "ERR")) | |
615 | { | |
f75f605a | 616 | com_err(whoami, 0, "Filesystem %s or %s is not AFS", |
617 | before[FS_NAME], after[FS_NAME]); | |
618 | return; | |
f78c7eaf | 619 | } |
620 | } | |
621 | com_err(whoami, 0, "Processing filesys %s", after[FS_NAME]); | |
f75f605a | 622 | abort_flag = 0; |
623 | while (1) | |
624 | { | |
625 | if ((rc = filesys_process(ldap_handle, dn_path, after[FS_NAME], | |
626 | after[FS_TYPE], after[FS_PACK], LDAP_MOD_ADD)) != LDAP_NO_SUCH_OBJECT) | |
627 | { | |
628 | if (rc != LDAP_SUCCESS) | |
629 | com_err(whoami, 0, "Couldn't process filesys %s", after[FS_NAME]); | |
630 | break; | |
631 | } | |
632 | if (abort_flag == 1) | |
633 | break; | |
634 | sleep(1); | |
635 | abort_flag = 1; | |
636 | if (rc = moira_connect()) | |
637 | { | |
638 | critical_alert("AD incremental", | |
639 | "Error contacting Moira server : %s", | |
640 | error_message(rc)); | |
641 | return; | |
642 | } | |
643 | av[0] = after[FS_NAME]; | |
644 | call_args[0] = (char *)ldap_handle; | |
645 | call_args[1] = dn_path; | |
89db421e | 646 | call_args[2] = ""; |
f75f605a | 647 | call_args[3] = NULL; |
648 | sid_base = NULL; | |
649 | sid_ptr = &sid_base; | |
5b8457c5 | 650 | callback_rc = 0; |
f75f605a | 651 | if (rc = mr_query("get_user_account_by_login", 1, av, user_create, |
652 | call_args)) | |
653 | { | |
654 | moira_disconnect(); | |
655 | com_err(whoami, 0, "Couldn't process filesys %s", after[FS_NAME]); | |
656 | break; | |
657 | } | |
5b8457c5 | 658 | if (callback_rc) |
659 | { | |
660 | moira_disconnect(); | |
661 | com_err(whoami, 0, "Couldn't process filesys %s", after[FS_NAME]); | |
662 | break; | |
663 | } | |
f75f605a | 664 | if (sid_base != NULL) |
665 | { | |
666 | sid_update(ldap_handle, dn_path); | |
667 | linklist_free(sid_base); | |
668 | sid_base = NULL; | |
669 | } | |
670 | moira_disconnect(); | |
671 | } | |
672 | ||
f78c7eaf | 673 | cleanup: |
f78c7eaf | 674 | return; |
675 | } | |
89db421e | 676 | |
677 | #define L_LIST_DESC 9 | |
678 | #define L_LIST_ID 10 | |
679 | ||
cd9e6b16 | 680 | void do_list(LDAP *ldap_handle, char *dn_path, char *ldap_hostname, |
681 | char **before, int beforec, char **after, int afterc) | |
5d0a7127 | 682 | { |
89db421e | 683 | int updateGroup; |
f75f605a | 684 | long rc; |
89db421e | 685 | char group_membership[6]; |
686 | char list_id[32]; | |
f75f605a | 687 | int security_flag; |
89db421e | 688 | char filter[128]; |
f75f605a | 689 | char group_ou[256]; |
89db421e | 690 | char before_list_id[32]; |
f75f605a | 691 | char before_group_membership[1]; |
692 | int before_security_flag; | |
693 | char before_group_ou[256]; | |
f75f605a | 694 | LK_ENTRY *ptr = NULL; |
9db0b148 | 695 | |
696 | if (beforec == 0 && afterc == 0) | |
697 | return; | |
698 | ||
89db421e | 699 | memset(list_id, '\0', sizeof(list_id)); |
700 | memset(before_list_id, '\0', sizeof(before_list_id)); | |
701 | memset(before_group_ou, '\0', sizeof(before_group_ou)); | |
702 | memset(before_group_membership, '\0', sizeof(before_group_membership)); | |
703 | memset(group_ou, '\0', sizeof(group_ou)); | |
704 | memset(group_membership, '\0', sizeof(group_membership)); | |
705 | updateGroup = 0; | |
706 | ||
707 | if (beforec > L_GID) | |
708 | { | |
709 | if (beforec < L_LIST_ID) | |
710 | return; | |
711 | if (beforec > L_LIST_DESC) | |
712 | { | |
713 | strcpy(before_list_id, before[L_LIST_ID]); | |
714 | } | |
f75f605a | 715 | before_security_flag = 0; |
f75f605a | 716 | get_group_membership(before_group_membership, before_group_ou, &before_security_flag, before); |
717 | } | |
89db421e | 718 | if (afterc > L_GID) |
f75f605a | 719 | { |
89db421e | 720 | if (afterc < L_LIST_ID) |
721 | return; | |
722 | if (afterc > L_LIST_DESC) | |
723 | { | |
724 | strcpy(list_id, before[L_LIST_ID]); | |
725 | } | |
f75f605a | 726 | security_flag = 0; |
f75f605a | 727 | get_group_membership(group_membership, group_ou, &security_flag, after); |
728 | } | |
89db421e | 729 | |
730 | if ((beforec == 0) && (afterc == 0)) /*this case should never happen*/ | |
f75f605a | 731 | return; |
cd9e6b16 | 732 | |
89db421e | 733 | updateGroup = 0; |
734 | if (beforec) | |
cd9e6b16 | 735 | { |
89db421e | 736 | updateGroup = 1; |
737 | if ((rc = process_group(ldap_handle, dn_path, before_list_id, before[L_NAME], | |
738 | before_group_ou, before_group_membership, | |
739 | before_security_flag, CHECK_GROUPS))) | |
740 | { | |
741 | if (rc == AD_NO_GROUPS_FOUND) | |
742 | updateGroup = 0; | |
743 | else | |
f75f605a | 744 | { |
89db421e | 745 | if ((rc == AD_WRONG_GROUP_DN_FOUND) || (rc == AD_MULTIPLE_GROUPS_FOUND)) |
746 | { | |
747 | rc = process_group(ldap_handle, dn_path, before_list_id, before[L_NAME], | |
748 | before_group_ou, before_group_membership, | |
749 | before_security_flag, CLEANUP_GROUPS); | |
750 | } | |
751 | if ((rc != AD_NO_GROUPS_FOUND) && (rc != 0)) | |
f75f605a | 752 | { |
89db421e | 753 | com_err(whoami, 0, "Could not change list name from %s to %s", |
754 | before[L_NAME], after[L_NAME]); | |
f75f605a | 755 | return; |
756 | } | |
89db421e | 757 | if (rc == AD_NO_GROUPS_FOUND) |
758 | updateGroup = 0; | |
759 | } | |
760 | } | |
761 | } | |
762 | ||
763 | if ((beforec != 0) && (afterc != 0)) | |
764 | { | |
765 | if (((strcmp(after[L_NAME], before[L_NAME])) || | |
766 | ((!strcmp(after[L_NAME], before[L_NAME])) && | |
767 | (strcmp(before_group_ou, group_ou)))) && | |
768 | (updateGroup == 1)) | |
769 | { | |
770 | com_err(whoami, 0, "Changing list name from %s to %s", | |
771 | before[L_NAME], after[L_NAME]); | |
772 | if ((strlen(before_group_ou) == 0) || (strlen(before_group_membership) == 0) || | |
773 | (strlen(group_ou) == 0) || (strlen(group_membership) == 0)) | |
774 | { | |
775 | com_err(whoami, 0, "%s", "couldn't find the group OU's"); | |
776 | return; | |
777 | } | |
778 | memset(filter, '\0', sizeof(filter)); | |
779 | if ((rc = group_rename(ldap_handle, dn_path, | |
780 | before[L_NAME], before_group_membership, | |
781 | before_group_ou, before_security_flag, before[L_LIST_DESC], | |
782 | after[L_NAME], group_membership, | |
783 | group_ou, security_flag, after[L_LIST_DESC], | |
784 | list_id, filter))) | |
785 | { | |
786 | if (rc != AD_NO_GROUPS_FOUND) | |
f75f605a | 787 | { |
89db421e | 788 | com_err(whoami, 0, "Could not change list name from %s to %s", |
789 | before[L_NAME], after[L_NAME]); | |
f75f605a | 790 | return; |
791 | } | |
89db421e | 792 | updateGroup = 0; |
f75f605a | 793 | } |
89db421e | 794 | beforec = 0; |
f75f605a | 795 | } |
796 | else | |
89db421e | 797 | beforec = 0; |
cd9e6b16 | 798 | } |
799 | ||
89db421e | 800 | if (beforec) |
984c91b7 | 801 | { |
f75f605a | 802 | if ((strlen(before_group_ou) == 0) || (strlen(before_group_membership) == 0)) |
984c91b7 | 803 | { |
f75f605a | 804 | com_err(whoami, 0, "couldn't find the group OU for group %s", before[L_NAME]); |
805 | return; | |
806 | } | |
984c91b7 | 807 | com_err(whoami, 0, "Deleting group %s", before[L_NAME]); |
89db421e | 808 | rc = group_delete(ldap_handle, dn_path, before[L_NAME], |
809 | before_group_membership, before_list_id); | |
f75f605a | 810 | return; |
5d0a7127 | 811 | } |
89db421e | 812 | if (afterc) |
5d0a7127 | 813 | { |
89db421e | 814 | if (!updateGroup) |
815 | { | |
816 | com_err(whoami, 0, "Creating group %s", after[L_NAME]); | |
817 | if (rc = process_group(ldap_handle, dn_path, list_id, after[L_NAME], | |
818 | group_ou, group_membership, | |
819 | security_flag, CHECK_GROUPS)) | |
820 | { | |
821 | if (rc != AD_NO_GROUPS_FOUND) | |
822 | { | |
823 | if ((rc == AD_WRONG_GROUP_DN_FOUND) || (rc == AD_MULTIPLE_GROUPS_FOUND)) | |
824 | { | |
825 | rc = process_group(ldap_handle, dn_path, list_id, after[L_NAME], | |
826 | group_ou, group_membership, | |
827 | security_flag, CLEANUP_GROUPS); | |
828 | } | |
829 | if (rc) | |
830 | { | |
831 | com_err(whoami, 0, "Could not create list %s", after[L_NAME]); | |
832 | return; | |
833 | } | |
834 | } | |
835 | } | |
836 | } | |
837 | else | |
838 | com_err(whoami, 0, "Updating group %s information", after[L_NAME]); | |
cd9e6b16 | 839 | |
f75f605a | 840 | if (rc = moira_connect()) |
841 | { | |
842 | critical_alert("AD incremental", | |
843 | "Error contacting Moira server : %s", | |
844 | error_message(rc)); | |
845 | return; | |
846 | } | |
847 | ||
89db421e | 848 | if (make_new_group(ldap_handle, dn_path, list_id, after[L_NAME], |
849 | group_ou, group_membership, security_flag, updateGroup)) | |
cd9e6b16 | 850 | { |
f75f605a | 851 | moira_disconnect(); |
f75f605a | 852 | return; |
cd9e6b16 | 853 | } |
89db421e | 854 | if (atoi(after[L_ACTIVE])) |
cd9e6b16 | 855 | { |
89db421e | 856 | populate_group(ldap_handle, dn_path, after[L_NAME], group_ou, |
857 | group_membership, security_flag, list_id); | |
cd9e6b16 | 858 | } |
f75f605a | 859 | moira_disconnect(); |
5d0a7127 | 860 | } |
f75f605a | 861 | |
862 | return; | |
5d0a7127 | 863 | } |
864 | ||
f75f605a | 865 | #define LM_EXTRA_ACTIVE (LM_END) |
866 | #define LM_EXTRA_PUBLIC (LM_END+1) | |
867 | #define LM_EXTRA_HIDDEN (LM_END+2) | |
868 | #define LM_EXTRA_MAILLIST (LM_END+3) | |
869 | #define LM_EXTRA_GROUP (LM_END+4) | |
870 | #define LM_EXTRA_GID (LM_END+5) | |
89db421e | 871 | #define LMN_LIST_ID (LM_END+6) |
872 | #define LM_LIST_ID (LM_END+7) | |
873 | #define LM_USER_ID (LM_END+8) | |
874 | #define LM_EXTRA_END (LM_END+9) | |
984c91b7 | 875 | |
5d0a7127 | 876 | void do_member(LDAP *ldap_handle, char *dn_path, char *ldap_hostname, |
cd9e6b16 | 877 | char **before, int beforec, char **after, int afterc) |
5d0a7127 | 878 | { |
cd9e6b16 | 879 | char group_name[128]; |
880 | char user_name[128]; | |
9db0b148 | 881 | char user_type[128]; |
89db421e | 882 | char moira_list_id[32]; |
883 | char moira_user_id[32]; | |
f75f605a | 884 | char group_membership[1]; |
f75f605a | 885 | char group_ou[256]; |
886 | char *args[16]; | |
887 | char **ptr; | |
89db421e | 888 | char *av[7]; |
889 | char *call_args[7]; | |
f75f605a | 890 | char *pUserOu; |
89db421e | 891 | int security_flag; |
892 | int rc; | |
f75f605a | 893 | |
894 | pUserOu = NULL; | |
895 | ptr = NULL; | |
89db421e | 896 | memset(moira_list_id, '\0', sizeof(moira_list_id)); |
897 | memset(moira_user_id, '\0', sizeof(moira_user_id)); | |
5d0a7127 | 898 | if (afterc) |
899 | { | |
89db421e | 900 | if (afterc < LM_EXTRA_GID) |
f75f605a | 901 | return; |
984c91b7 | 902 | if (!atoi(after[LM_EXTRA_ACTIVE])) |
cd9e6b16 | 903 | return; |
f75f605a | 904 | ptr = after; |
89db421e | 905 | if (!strcasecmp(ptr[LM_TYPE], "LIST")) |
906 | return; | |
984c91b7 | 907 | strcpy(user_name, after[LM_MEMBER]); |
908 | strcpy(group_name, after[LM_LIST]); | |
909 | strcpy(user_type, after[LM_TYPE]); | |
89db421e | 910 | if (!strcasecmp(ptr[LM_TYPE], "USER")) |
911 | { | |
912 | if (afterc > LMN_LIST_ID) | |
913 | { | |
914 | strcpy(moira_list_id, after[LM_LIST_ID]); | |
915 | strcpy(moira_user_id, after[LM_USER_ID]); | |
916 | } | |
917 | } | |
918 | else | |
919 | { | |
920 | if (afterc > LM_EXTRA_GID) | |
921 | strcpy(moira_list_id, after[LMN_LIST_ID]); | |
922 | } | |
5d0a7127 | 923 | } |
924 | else if (beforec) | |
925 | { | |
89db421e | 926 | if (beforec < LM_EXTRA_GID) |
f75f605a | 927 | return; |
984c91b7 | 928 | if (!atoi(before[LM_EXTRA_ACTIVE])) |
9db0b148 | 929 | return; |
f75f605a | 930 | ptr = before; |
89db421e | 931 | if (!strcasecmp(ptr[LM_TYPE], "LIST")) |
932 | return; | |
984c91b7 | 933 | strcpy(user_name, before[LM_MEMBER]); |
934 | strcpy(group_name, before[LM_LIST]); | |
935 | strcpy(user_type, before[LM_TYPE]); | |
89db421e | 936 | if (!strcasecmp(ptr[LM_TYPE], "USER")) |
937 | { | |
938 | if (beforec > LMN_LIST_ID) | |
939 | { | |
940 | strcpy(moira_list_id, before[LM_LIST_ID]); | |
941 | strcpy(moira_user_id, before[LM_USER_ID]); | |
942 | } | |
943 | } | |
944 | else | |
945 | { | |
946 | if (beforec > LM_EXTRA_GID) | |
947 | strcpy(moira_list_id, before[LMN_LIST_ID]); | |
948 | } | |
5d0a7127 | 949 | } |
cd9e6b16 | 950 | |
f75f605a | 951 | if (ptr == NULL) |
952 | return; | |
953 | ||
954 | args[L_NAME] = ptr[LM_LIST]; | |
955 | args[L_ACTIVE] = ptr[LM_EXTRA_ACTIVE]; | |
956 | args[L_PUBLIC] = ptr[LM_EXTRA_PUBLIC]; | |
957 | args[L_HIDDEN] = ptr[LM_EXTRA_HIDDEN]; | |
958 | args[L_MAILLIST] = ptr[LM_EXTRA_MAILLIST]; | |
959 | args[L_GROUP] = ptr[LM_EXTRA_GROUP]; | |
960 | args[L_GID] = ptr[LM_EXTRA_GID]; | |
961 | ||
962 | security_flag = 0; | |
963 | memset(group_ou, '\0', sizeof(group_ou)); | |
964 | get_group_membership(group_membership, group_ou, &security_flag, args); | |
965 | if (strlen(group_ou) == 0) | |
cd9e6b16 | 966 | { |
f75f605a | 967 | com_err(whoami, 0, "couldn't find the group OU for group %s", group_name); |
cd9e6b16 | 968 | return; |
969 | } | |
89db421e | 970 | if (rc = process_group(ldap_handle, dn_path, moira_list_id, group_name, group_ou, group_membership, security_flag, CHECK_GROUPS)) |
971 | { | |
972 | if (rc != AD_NO_GROUPS_FOUND) | |
973 | { | |
974 | if (rc = process_group(ldap_handle, dn_path, moira_list_id, group_name, group_ou, group_membership, security_flag, CLEANUP_GROUPS)) | |
975 | { | |
976 | if (rc != AD_NO_GROUPS_FOUND) | |
977 | { | |
978 | if (afterc) | |
979 | com_err(whoami, 0, "Couldn't add %s to group %s - unable to process group", user_name, group_name); | |
980 | else | |
c0bd7667 | 981 | com_err(whoami, 0, "Couldn't remove %s from group %s - unable to process group", user_name, group_name); |
89db421e | 982 | return; |
983 | } | |
984 | } | |
985 | } | |
986 | } | |
987 | if (rc == AD_NO_GROUPS_FOUND) | |
988 | { | |
989 | if (rc = moira_connect()) | |
990 | { | |
991 | critical_alert("AD incremental", | |
992 | "Error contacting Moira server : %s", | |
993 | error_message(rc)); | |
994 | return; | |
995 | } | |
f75f605a | 996 | |
89db421e | 997 | com_err(whoami, 0, "creating group %s", group_name); |
998 | if (make_new_group(ldap_handle, dn_path, moira_list_id, ptr[LM_LIST], | |
999 | group_ou, group_membership, security_flag, 0)) | |
1000 | { | |
1001 | moira_disconnect(); | |
1002 | return; | |
1003 | } | |
1004 | if (atoi(ptr[LM_EXTRA_ACTIVE])) | |
1005 | { | |
1006 | populate_group(ldap_handle, dn_path, ptr[LM_LIST], group_ou, | |
1007 | group_membership, security_flag, moira_list_id); | |
1008 | } | |
1009 | moira_disconnect(); | |
1010 | } | |
f75f605a | 1011 | rc = 0; |
1012 | if (beforec) | |
1013 | { | |
89db421e | 1014 | com_err(whoami, 0, "removing user %s from list %s", user_name, group_name); |
f75f605a | 1015 | pUserOu = user_ou; |
1016 | if (!strcasecmp(ptr[LM_TYPE], "STRING")) | |
cd9e6b16 | 1017 | { |
f75f605a | 1018 | if (contact_create(ldap_handle, dn_path, ptr[LM_MEMBER], contact_ou)) |
1019 | return; | |
1020 | pUserOu = contact_ou; | |
1021 | } | |
1022 | else if (!strcasecmp(ptr[LM_TYPE], "KERBEROS")) | |
1023 | { | |
1024 | if (contact_create(ldap_handle, dn_path, ptr[LM_MEMBER], kerberos_ou)) | |
1025 | return; | |
1026 | pUserOu = kerberos_ou; | |
1027 | } | |
89db421e | 1028 | if (rc = member_remove(ldap_handle, dn_path, group_name, |
1029 | group_ou, group_membership, ptr[LM_MEMBER], | |
1030 | pUserOu, moira_list_id)) | |
c0bd7667 | 1031 | com_err(whoami, 0, "couldn't remove %s from group %s", user_name, group_name); |
89db421e | 1032 | return; |
f75f605a | 1033 | } |
89db421e | 1034 | |
1035 | com_err(whoami, 0, "Adding %s to list %s", user_name, group_name); | |
1036 | pUserOu = user_ou; | |
1037 | if (!strcasecmp(ptr[LM_TYPE], "STRING")) | |
f75f605a | 1038 | { |
89db421e | 1039 | if (contact_create(ldap_handle, dn_path, ptr[LM_MEMBER], contact_ou)) |
f75f605a | 1040 | return; |
89db421e | 1041 | pUserOu = contact_ou; |
1042 | } | |
1043 | else if (!strcasecmp(ptr[LM_TYPE], "KERBEROS")) | |
1044 | { | |
1045 | if (contact_create(ldap_handle, dn_path, ptr[LM_MEMBER], kerberos_ou)) | |
1046 | return; | |
1047 | pUserOu = kerberos_ou; | |
1048 | } | |
1049 | else if (!strcasecmp(ptr[LM_TYPE], "USER")) | |
1050 | { | |
1051 | if ((rc = check_user(ldap_handle, dn_path, ptr[LM_MEMBER], | |
1052 | moira_user_id)) == AD_NO_USER_FOUND) | |
f75f605a | 1053 | { |
89db421e | 1054 | if (rc = moira_connect()) |
1055 | { | |
1056 | critical_alert("AD incremental", | |
1057 | "Error connection to Moira : %s", | |
1058 | error_message(rc)); | |
1059 | return; | |
1060 | } | |
1061 | com_err(whoami, 0, "creating user %s", after[U_NAME]); | |
1062 | av[0] = ptr[LM_MEMBER]; | |
1063 | call_args[0] = (char *)ldap_handle; | |
1064 | call_args[1] = dn_path; | |
1065 | call_args[2] = moira_user_id; | |
1066 | call_args[3] = NULL; | |
1067 | sid_base = NULL; | |
1068 | sid_ptr = &sid_base; | |
1069 | callback_rc = 0; | |
1070 | if (rc = mr_query("get_user_account_by_login", 1, av, user_create, | |
1071 | call_args)) | |
1072 | { | |
1073 | moira_disconnect(); | |
1074 | com_err(whoami, 0, "couldn't create user %s : %s", | |
1075 | ptr[LM_MEMBER], error_message(rc)); | |
1076 | return; | |
1077 | } | |
1078 | if (callback_rc) | |
1079 | { | |
1080 | moira_disconnect(); | |
1081 | com_err(whoami, 0, "couldn't create user %s", ptr[LM_MEMBER]); | |
1082 | return; | |
1083 | } | |
1084 | sleep(1); | |
1085 | if (sid_base != NULL) | |
1086 | { | |
1087 | sid_update(ldap_handle, dn_path); | |
1088 | linklist_free(sid_base); | |
1089 | } | |
f75f605a | 1090 | } |
89db421e | 1091 | else |
f75f605a | 1092 | { |
89db421e | 1093 | if (rc != 0) |
f75f605a | 1094 | return; |
cd9e6b16 | 1095 | } |
89db421e | 1096 | pUserOu = user_ou; |
cd9e6b16 | 1097 | } |
89db421e | 1098 | |
1099 | if (rc = member_add(ldap_handle, dn_path, group_name, | |
1100 | group_ou, group_membership, ptr[LM_MEMBER], | |
1101 | pUserOu, moira_list_id)) | |
cd9e6b16 | 1102 | { |
89db421e | 1103 | com_err(whoami, 0, "couldn't add %s to group %s", user_name, group_name); |
f75f605a | 1104 | } |
1105 | return; | |
5d0a7127 | 1106 | } |
1107 | ||
cd9e6b16 | 1108 | |
89db421e | 1109 | #define U_USER_ID 10 |
1110 | ||
f78c7eaf | 1111 | void do_user(LDAP *ldap_handle, char *dn_path, char *ldap_hostname, |
1112 | char **before, int beforec, char **after, | |
cd9e6b16 | 1113 | int afterc) |
5d0a7127 | 1114 | { |
984c91b7 | 1115 | int rc; |
89db421e | 1116 | char *av[7]; |
1117 | char after_user_id[32]; | |
1118 | char before_user_id[32]; | |
1119 | char *call_args[7]; | |
984c91b7 | 1120 | |
5b8457c5 | 1121 | if ((beforec == 0) && (afterc == 0)) |
984c91b7 | 1122 | return; |
1123 | ||
89db421e | 1124 | memset(after_user_id, '\0', sizeof(after_user_id)); |
1125 | memset(before_user_id, '\0', sizeof(before_user_id)); | |
1126 | if (beforec > U_USER_ID) | |
1127 | strcpy(before_user_id, before[U_USER_ID]); | |
1128 | if (afterc > U_USER_ID) | |
1129 | strcpy(after_user_id, after[U_USER_ID]); | |
984c91b7 | 1130 | |
89db421e | 1131 | if ((beforec == 0) && (afterc == 0)) /*this case should never happen */ |
984c91b7 | 1132 | return; |
cd9e6b16 | 1133 | |
89db421e | 1134 | if ((beforec == 0) && (afterc != 0)) /*this case only happens when the account*/ |
1135 | return; /*account is first created but not usable*/ | |
f75f605a | 1136 | |
89db421e | 1137 | if ((beforec != 0) && (afterc == 0)) /*this case only happens when the account*/ |
1138 | { /*is expunged*/ | |
1139 | if (atoi(before[U_STATE]) == 0) | |
cd9e6b16 | 1140 | { |
89db421e | 1141 | com_err(whoami, 0, "expunging user %s from AD", before[U_NAME]); |
1142 | user_delete(ldap_handle, dn_path, before[U_NAME], before_user_id); | |
cd9e6b16 | 1143 | } |
f75f605a | 1144 | return; |
5d0a7127 | 1145 | } |
f75f605a | 1146 | |
89db421e | 1147 | /*process anything that gets here*/ |
c0bd7667 | 1148 | if ((rc = check_user(ldap_handle, dn_path, before[U_NAME], |
1149 | before_user_id)) == AD_NO_USER_FOUND) | |
5d0a7127 | 1150 | { |
6c8f12af | 1151 | if (!check_string(after[U_NAME])) |
1152 | return; | |
f75f605a | 1153 | if (rc = moira_connect()) |
1154 | { | |
1155 | critical_alert("AD incremental", | |
1156 | "Error connection to Moira : %s", | |
1157 | error_message(rc)); | |
1158 | return; | |
1159 | } | |
89db421e | 1160 | com_err(whoami, 0, "creating user %s", after[U_NAME]); |
5d0a7127 | 1161 | |
984c91b7 | 1162 | av[0] = after[U_NAME]; |
cd9e6b16 | 1163 | call_args[0] = (char *)ldap_handle; |
1164 | call_args[1] = dn_path; | |
89db421e | 1165 | call_args[2] = after_user_id; |
9db0b148 | 1166 | call_args[3] = NULL; |
cd9e6b16 | 1167 | sid_base = NULL; |
1168 | sid_ptr = &sid_base; | |
5b8457c5 | 1169 | callback_rc = 0; |
cd9e6b16 | 1170 | if (rc = mr_query("get_user_account_by_login", 1, av, user_create, |
1171 | call_args)) | |
1172 | { | |
f75f605a | 1173 | moira_disconnect(); |
89db421e | 1174 | com_err(whoami, 0, "couldn't create user %s : %s", |
f75f605a | 1175 | after[U_NAME], error_message(rc)); |
1176 | return; | |
cd9e6b16 | 1177 | } |
5b8457c5 | 1178 | if (callback_rc) |
1179 | { | |
1180 | moira_disconnect(); | |
89db421e | 1181 | com_err(whoami, 0, "couldn't create user %s", after[U_NAME]); |
5b8457c5 | 1182 | return; |
1183 | } | |
f75f605a | 1184 | sleep(1); |
cd9e6b16 | 1185 | if (sid_base != NULL) |
1186 | { | |
1187 | sid_update(ldap_handle, dn_path); | |
1188 | linklist_free(sid_base); | |
1189 | } | |
89db421e | 1190 | return; |
1191 | } | |
1192 | else | |
1193 | { | |
1194 | if (rc != 0) | |
1195 | return; | |
1196 | } | |
1197 | if (strcmp(before[U_NAME], after[U_NAME])) | |
1198 | { | |
1199 | if ((check_string(before[U_NAME])) && (check_string(after[U_NAME]))) | |
f75f605a | 1200 | { |
89db421e | 1201 | com_err(whoami, 0, "changing user %s to %s", |
1202 | before[U_NAME], after[U_NAME]); | |
1203 | if ((rc = user_rename(ldap_handle, dn_path, before[U_NAME], | |
1204 | after[U_NAME])) != LDAP_SUCCESS) | |
f75f605a | 1205 | { |
89db421e | 1206 | return; |
f75f605a | 1207 | } |
1208 | } | |
cd9e6b16 | 1209 | } |
89db421e | 1210 | com_err(whoami, 0, "updating user %s information", after[U_NAME]); |
1211 | rc = user_update(ldap_handle, dn_path, after[U_NAME], | |
1212 | after[U_UID], after[U_MITID], | |
1213 | after_user_id, atoi(after[U_STATE])); | |
f75f605a | 1214 | return; |
5d0a7127 | 1215 | } |
1216 | ||
1217 | int construct_newvalues(LK_ENTRY *linklist_base, int modvalue_count, | |
cd9e6b16 | 1218 | char *oldValue, char *newValue, |
1219 | char ***modvalues, int type) | |
5d0a7127 | 1220 | { |
cd9e6b16 | 1221 | LK_ENTRY *linklist_ptr; |
1222 | int i; | |
1223 | char *cPtr; | |
5d0a7127 | 1224 | |
cd9e6b16 | 1225 | if (((*modvalues) = calloc(1, (modvalue_count + 1) * sizeof(char *))) |
1226 | == NULL) | |
1227 | { | |
1228 | return(1); | |
1229 | } | |
5d0a7127 | 1230 | for (i = 0; i < (modvalue_count + 1); i++) |
cd9e6b16 | 1231 | (*modvalues)[i] = NULL; |
5d0a7127 | 1232 | if (modvalue_count != 0) |
1233 | { | |
1234 | linklist_ptr = linklist_base; | |
1235 | for (i = 0; i < modvalue_count; i++) | |
cd9e6b16 | 1236 | { |
1237 | if ((oldValue != NULL) && (newValue != NULL)) | |
1238 | { | |
1239 | if ((cPtr = (char *)strstr(linklist_ptr->value, oldValue)) | |
1240 | != (char *)NULL) | |
1241 | { | |
1242 | if (type == REPLACE) | |
1243 | { | |
1244 | if (((*modvalues)[i] = calloc(1, strlen(newValue) + 1)) | |
1245 | == NULL) | |
1246 | return(1); | |
1247 | memset((*modvalues)[i], '\0', strlen(newValue) + 1); | |
1248 | strcpy((*modvalues)[i], newValue); | |
1249 | } | |
1250 | else | |
1251 | { | |
1252 | if (((*modvalues)[i] = calloc(1, | |
1253 | (int)(cPtr - linklist_ptr->value) + | |
1254 | (linklist_ptr->length - strlen(oldValue)) + | |
1255 | strlen(newValue) + 1)) == NULL) | |
1256 | return(1); | |
1257 | memset((*modvalues)[i], '\0', | |
1258 | (int)(cPtr - linklist_ptr->value) + | |
1259 | (linklist_ptr->length - strlen(oldValue)) + | |
1260 | strlen(newValue) + 1); | |
1261 | memcpy((*modvalues)[i], linklist_ptr->value, | |
1262 | (int)(cPtr - linklist_ptr->value)); | |
1263 | strcat((*modvalues)[i], newValue); | |
1264 | strcat((*modvalues)[i], | |
1265 | &linklist_ptr->value[(int)(cPtr - linklist_ptr->value) + strlen(oldValue)]); | |
1266 | } | |
1267 | } | |
1268 | else | |
1269 | { | |
1270 | (*modvalues)[i] = calloc(1, linklist_ptr->length + 1); | |
1271 | memset((*modvalues)[i], '\0', linklist_ptr->length + 1); | |
1272 | memcpy((*modvalues)[i], linklist_ptr->value, | |
1273 | linklist_ptr->length); | |
1274 | } | |
1275 | } | |
1276 | else | |
1277 | { | |
1278 | (*modvalues)[i] = calloc(1, linklist_ptr->length + 1); | |
1279 | memset((*modvalues)[i], '\0', linklist_ptr->length + 1); | |
1280 | memcpy((*modvalues)[i], linklist_ptr->value, | |
1281 | linklist_ptr->length); | |
1282 | } | |
1283 | linklist_ptr = linklist_ptr->next; | |
1284 | } | |
1285 | (*modvalues)[i] = NULL; | |
5d0a7127 | 1286 | } |
1287 | return(0); | |
1288 | } | |
1289 | ||
cd9e6b16 | 1290 | |
5d0a7127 | 1291 | int linklist_build(LDAP *ldap_handle, char *dn_path, char *search_exp, |
cd9e6b16 | 1292 | char **attr_array, LK_ENTRY **linklist_base, |
1293 | int *linklist_count) | |
5d0a7127 | 1294 | { |
cd9e6b16 | 1295 | ULONG rc; |
5d0a7127 | 1296 | LDAPMessage *ldap_entry; |
cd9e6b16 | 1297 | |
1298 | rc = 0; | |
5d0a7127 | 1299 | ldap_entry = NULL; |
1300 | (*linklist_base) = NULL; | |
1301 | (*linklist_count) = 0; | |
1302 | if ((rc = ldap_search_s(ldap_handle, dn_path, LDAP_SCOPE_SUBTREE, | |
cd9e6b16 | 1303 | search_exp, attr_array, 0, &ldap_entry)) |
5d0a7127 | 1304 | != LDAP_SUCCESS) |
6c8f12af | 1305 | { |
1306 | if (rc != LDAP_SIZELIMIT_EXCEEDED) | |
1307 | return(0); | |
1308 | } | |
1309 | ||
cd9e6b16 | 1310 | rc = retrieve_entries(ldap_handle, ldap_entry, linklist_base, linklist_count); |
1311 | ||
5d0a7127 | 1312 | ldap_msgfree(ldap_entry); |
1313 | return(rc); | |
1314 | } | |
1315 | ||
cd9e6b16 | 1316 | |
5d0a7127 | 1317 | int retrieve_entries(LDAP *ldap_handle, LDAPMessage *ldap_entry, |
cd9e6b16 | 1318 | LK_ENTRY **linklist_base, int *linklist_count) |
5d0a7127 | 1319 | { |
cd9e6b16 | 1320 | char distinguished_name[1024]; |
1321 | LK_ENTRY *linklist_ptr; | |
1322 | int rc; | |
1323 | ||
5d0a7127 | 1324 | if ((ldap_entry = ldap_first_entry(ldap_handle, ldap_entry)) == NULL) |
1325 | return(0); | |
cd9e6b16 | 1326 | |
1327 | memset(distinguished_name, '\0', sizeof(distinguished_name)); | |
1328 | get_distinguished_name(ldap_handle, ldap_entry, distinguished_name); | |
1329 | ||
1330 | if ((rc = retrieve_attributes(ldap_handle, ldap_entry, distinguished_name, | |
1331 | linklist_base)) != 0) | |
5d0a7127 | 1332 | return(rc); |
cd9e6b16 | 1333 | |
5d0a7127 | 1334 | while ((ldap_entry = ldap_next_entry(ldap_handle, ldap_entry)) != NULL) |
1335 | { | |
cd9e6b16 | 1336 | memset(distinguished_name, '\0', sizeof(distinguished_name)); |
1337 | get_distinguished_name(ldap_handle, ldap_entry, distinguished_name); | |
1338 | ||
1339 | if ((rc = retrieve_attributes(ldap_handle, ldap_entry, distinguished_name, | |
1340 | linklist_base)) != 0) | |
1341 | return(rc); | |
5d0a7127 | 1342 | } |
cd9e6b16 | 1343 | |
5d0a7127 | 1344 | linklist_ptr = (*linklist_base); |
1345 | (*linklist_count) = 0; | |
1346 | while (linklist_ptr != NULL) | |
1347 | { | |
1348 | ++(*linklist_count); | |
1349 | linklist_ptr = linklist_ptr->next; | |
1350 | } | |
1351 | return(0); | |
1352 | } | |
1353 | ||
1354 | int retrieve_attributes(LDAP *ldap_handle, LDAPMessage *ldap_entry, | |
cd9e6b16 | 1355 | char *distinguished_name, LK_ENTRY **linklist_current) |
5d0a7127 | 1356 | { |
cd9e6b16 | 1357 | char *Attribute; |
1358 | BerElement *ptr; | |
1359 | ||
5d0a7127 | 1360 | ptr = NULL; |
cd9e6b16 | 1361 | if ((Attribute = ldap_first_attribute(ldap_handle, ldap_entry, &ptr)) != NULL) |
5d0a7127 | 1362 | { |
cd9e6b16 | 1363 | retrieve_values(ldap_handle, ldap_entry, Attribute, distinguished_name, |
1364 | linklist_current); | |
5d0a7127 | 1365 | ldap_memfree(Attribute); |
cd9e6b16 | 1366 | while ((Attribute = ldap_next_attribute(ldap_handle, ldap_entry, |
1367 | ptr)) != NULL) | |
1368 | { | |
1369 | retrieve_values(ldap_handle, ldap_entry, Attribute, | |
1370 | distinguished_name, linklist_current); | |
1371 | ldap_memfree(Attribute); | |
1372 | } | |
5d0a7127 | 1373 | } |
cd9e6b16 | 1374 | ldap_ber_free(ptr, 0); |
5d0a7127 | 1375 | return(0); |
1376 | } | |
1377 | ||
cd9e6b16 | 1378 | int retrieve_values(LDAP *ldap_handle, LDAPMessage *ldap_entry, |
1379 | char *Attribute, char *distinguished_name, | |
1380 | LK_ENTRY **linklist_current) | |
5d0a7127 | 1381 | { |
cd9e6b16 | 1382 | char **str_value; |
1383 | char temp[256]; | |
1384 | void **Ptr; | |
1385 | int use_bervalue; | |
1386 | LK_ENTRY *linklist_previous; | |
5d0a7127 | 1387 | LDAP_BERVAL **ber_value; |
cd9e6b16 | 1388 | DWORD ber_length; |
5d0a7127 | 1389 | #ifdef LDAP_DEBUG |
cd9e6b16 | 1390 | SID *sid; |
1391 | GUID *guid; | |
1392 | int i; | |
1393 | int intValue; | |
1394 | DWORD *subauth; | |
1395 | SID_IDENTIFIER_AUTHORITY *sid_auth; | |
1396 | unsigned char *subauth_count; | |
1397 | #endif /*LDAP_BEGUG*/ | |
5d0a7127 | 1398 | |
1399 | use_bervalue = 0; | |
1400 | memset(temp, '\0', sizeof(temp)); | |
1401 | if ((!strcmp(Attribute, "objectSid")) || | |
1402 | (!strcmp(Attribute, "objectGUID"))) | |
1403 | use_bervalue = 1; | |
cd9e6b16 | 1404 | |
5d0a7127 | 1405 | if (use_bervalue) |
1406 | { | |
1407 | ber_value = ldap_get_values_len(ldap_handle, ldap_entry, Attribute); | |
1408 | Ptr = (void **)ber_value; | |
1409 | str_value = NULL; | |
cd9e6b16 | 1410 | } |
5d0a7127 | 1411 | else |
1412 | { | |
1413 | str_value = ldap_get_values(ldap_handle, ldap_entry, Attribute); | |
1414 | Ptr = (void **)str_value; | |
1415 | ber_value = NULL; | |
1416 | } | |
1417 | if (Ptr != NULL) | |
1418 | { | |
1419 | for (; *Ptr; Ptr++) | |
cd9e6b16 | 1420 | { |
1421 | if ((linklist_previous = calloc(1, sizeof(LK_ENTRY))) == NULL) | |
1422 | return(1); | |
1423 | memset(linklist_previous, '\0', sizeof(LK_ENTRY)); | |
1424 | linklist_previous->next = (*linklist_current); | |
1425 | (*linklist_current) = linklist_previous; | |
1426 | ||
1427 | if (((*linklist_current)->attribute = calloc(1, | |
1428 | strlen(Attribute) + 1)) == NULL) | |
1429 | return(1); | |
1430 | memset((*linklist_current)->attribute, '\0', strlen(Attribute) + 1); | |
1431 | strcpy((*linklist_current)->attribute, Attribute); | |
1432 | if (use_bervalue) | |
1433 | { | |
1434 | ber_length = (*(LDAP_BERVAL **)Ptr)->bv_len; | |
1435 | if (((*linklist_current)->value = calloc(1, ber_length)) == NULL) | |
1436 | return(1); | |
1437 | memset((*linklist_current)->value, '\0', ber_length); | |
1438 | memcpy((*linklist_current)->value, (*(LDAP_BERVAL **)Ptr)->bv_val, | |
1439 | ber_length); | |
1440 | (*linklist_current)->length = ber_length; | |
1441 | } | |
1442 | else | |
1443 | { | |
1444 | if (((*linklist_current)->value = calloc(1, | |
1445 | strlen(*Ptr) + 1)) == NULL) | |
1446 | return(1); | |
1447 | memset((*linklist_current)->value, '\0', strlen(*Ptr) + 1); | |
1448 | (*linklist_current)->length = strlen(*Ptr); | |
1449 | strcpy((*linklist_current)->value, *Ptr); | |
1450 | } | |
1451 | (*linklist_current)->ber_value = use_bervalue; | |
1452 | if (((*linklist_current)->dn = calloc(1, | |
1453 | strlen(distinguished_name) + 1)) == NULL) | |
1454 | return(1); | |
1455 | memset((*linklist_current)->dn, '\0', strlen(distinguished_name) + 1); | |
1456 | strcpy((*linklist_current)->dn, distinguished_name); | |
1457 | ||
5d0a7127 | 1458 | #ifdef LDAP_DEBUG |
cd9e6b16 | 1459 | if (!strcmp(Attribute, "objectGUID")) |
1460 | { | |
1461 | guid = (GUID *)((*linklist_current)->value); | |
1462 | sprintf(temp, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", | |
1463 | guid->Data1, guid->Data2, guid->Data3, | |
1464 | guid->Data4[0], guid->Data4[1], guid->Data4[2], | |
1465 | guid->Data4[3], guid->Data4[4], guid->Data4[5], | |
1466 | guid->Data4[6], guid->Data4[7]); | |
1467 | print_to_screen(" %20s : {%s}\n", Attribute, temp); | |
1468 | } | |
1469 | else if (!strcmp(Attribute, "objectSid")) | |
1470 | { | |
1471 | sid = (SID *)((*(LDAP_BERVAL **)Ptr)->bv_val); | |
5d0a7127 | 1472 | #ifdef _WIN32 |
cd9e6b16 | 1473 | print_to_screen(" Revision = %d\n", sid->Revision); |
1474 | print_to_screen(" SID Identifier Authority:\n"); | |
1475 | sid_auth = &sid->IdentifierAuthority; | |
1476 | if (sid_auth->Value[0]) | |
1477 | print_to_screen(" SECURITY_NULL_SID_AUTHORITY\n"); | |
1478 | else if (sid_auth->Value[1]) | |
1479 | print_to_screen(" SECURITY_WORLD_SID_AUTHORITY\n"); | |
1480 | else if (sid_auth->Value[2]) | |
1481 | print_to_screen(" SECURITY_LOCAL_SID_AUTHORITY\n"); | |
1482 | else if (sid_auth->Value[3]) | |
1483 | print_to_screen(" SECURITY_CREATOR_SID_AUTHORITY\n"); | |
1484 | else if (sid_auth->Value[5]) | |
1485 | print_to_screen(" SECURITY_NT_AUTHORITY\n"); | |
1486 | else | |
1487 | print_to_screen(" UNKNOWN SID AUTHORITY\n"); | |
1488 | subauth_count = GetSidSubAuthorityCount(sid); | |
1489 | print_to_screen(" SidSubAuthorityCount = %d\n", | |
1490 | *subauth_count); | |
1491 | print_to_screen(" SidSubAuthority:\n"); | |
1492 | for (i = 0; i < *subauth_count; i++) | |
1493 | { | |
1494 | if ((subauth = GetSidSubAuthority(sid, i)) != NULL) | |
1495 | print_to_screen(" %u\n", *subauth); | |
1496 | } | |
5d0a7127 | 1497 | #endif |
cd9e6b16 | 1498 | } |
1499 | else if ((!memcmp(Attribute, "userAccountControl", | |
1500 | strlen("userAccountControl"))) || | |
1501 | (!memcmp(Attribute, "sAMAccountType", | |
1502 | strlen("sAmAccountType")))) | |
1503 | { | |
1504 | intValue = atoi(*Ptr); | |
1505 | print_to_screen(" %20s : %ld\n",Attribute, intValue); | |
1506 | if (!memcmp(Attribute, "userAccountControl", | |
1507 | strlen("userAccountControl"))) | |
1508 | { | |
1509 | if (intValue & UF_ACCOUNTDISABLE) | |
1510 | print_to_screen(" %20s : %s\n", | |
1511 | "", "Account disabled"); | |
1512 | else | |
1513 | print_to_screen(" %20s : %s\n", | |
1514 | "", "Account active"); | |
1515 | if (intValue & UF_HOMEDIR_REQUIRED) | |
1516 | print_to_screen(" %20s : %s\n", | |
1517 | "", "Home directory required"); | |
1518 | if (intValue & UF_LOCKOUT) | |
1519 | print_to_screen(" %20s : %s\n", | |
1520 | "", "Account locked out"); | |
1521 | if (intValue & UF_PASSWD_NOTREQD) | |
1522 | print_to_screen(" %20s : %s\n", | |
1523 | "", "No password required"); | |
1524 | if (intValue & UF_PASSWD_CANT_CHANGE) | |
1525 | print_to_screen(" %20s : %s\n", | |
1526 | "", "Cannot change password"); | |
1527 | if (intValue & UF_TEMP_DUPLICATE_ACCOUNT) | |
1528 | print_to_screen(" %20s : %s\n", | |
1529 | "", "Temp duplicate account"); | |
1530 | if (intValue & UF_NORMAL_ACCOUNT) | |
1531 | print_to_screen(" %20s : %s\n", | |
1532 | "", "Normal account"); | |
1533 | if (intValue & UF_INTERDOMAIN_TRUST_ACCOUNT) | |
1534 | print_to_screen(" %20s : %s\n", | |
1535 | "", "Interdomain trust account"); | |
1536 | if (intValue & UF_WORKSTATION_TRUST_ACCOUNT) | |
1537 | print_to_screen(" %20s : %s\n", | |
1538 | "", "Workstation trust account"); | |
1539 | if (intValue & UF_SERVER_TRUST_ACCOUNT) | |
1540 | print_to_screen(" %20s : %s\n", | |
1541 | "", "Server trust account"); | |
1542 | } | |
1543 | } | |
1544 | else | |
1545 | { | |
1546 | print_to_screen(" %20s : %s\n",Attribute, *Ptr); | |
1547 | } | |
5d0a7127 | 1548 | #endif /*LDAP_DEBUG*/ |
cd9e6b16 | 1549 | } |
5d0a7127 | 1550 | if (str_value != NULL) |
cd9e6b16 | 1551 | ldap_value_free(str_value); |
5d0a7127 | 1552 | if (ber_value != NULL) |
cd9e6b16 | 1553 | ldap_value_free_len(ber_value); |
5d0a7127 | 1554 | } |
1555 | (*linklist_current) = linklist_previous; | |
1556 | return(0); | |
1557 | } | |
1558 | ||
5d0a7127 | 1559 | int moira_connect(void) |
1560 | { | |
cd9e6b16 | 1561 | long rc; |
1562 | char HostName[64]; | |
1563 | ||
5d0a7127 | 1564 | if (!mr_connections++) |
1565 | { | |
1566 | #ifdef _WIN32 | |
1567 | memset(HostName, '\0', sizeof(HostName)); | |
1568 | strcpy(HostName, "ttsp"); | |
cd9e6b16 | 1569 | rc = mr_connect_cl(HostName, "winad.incr", QUERY_VERSION, 1); |
1570 | /*det | |
5d0a7127 | 1571 | rc = mr_connect(HostName); |
cd9e6b16 | 1572 | */ |
5d0a7127 | 1573 | #else |
1574 | struct utsname uts; | |
1575 | uname(&uts); | |
cd9e6b16 | 1576 | rc = mr_connect_cl(uts.nodename, "winad.incr", QUERY_VERSION, 1); |
1577 | /* | |
5d0a7127 | 1578 | rc = mr_connect(uts.nodename); |
cd9e6b16 | 1579 | */ |
5d0a7127 | 1580 | #endif /*WIN32*/ |
cd9e6b16 | 1581 | /*det |
5d0a7127 | 1582 | if (!rc) |
cd9e6b16 | 1583 | rc = mr_auth("winad.incr"); |
1584 | */ | |
5d0a7127 | 1585 | return rc; |
1586 | } | |
1587 | return 0; | |
1588 | } | |
1589 | ||
0d958b3c | 1590 | void check_winad(void) |
1591 | { | |
1592 | int i; | |
1593 | ||
1594 | for (i = 0; file_exists(STOP_FILE); i++) | |
1595 | { | |
1596 | if (i > 30) | |
1597 | { | |
f75f605a | 1598 | critical_alert("AD incremental", |
f78c7eaf | 1599 | "WINAD incremental failed (%s exists): %s", |
1600 | STOP_FILE, tbl_buf); | |
1601 | exit(1); | |
1602 | } | |
0d958b3c | 1603 | sleep(60); |
1604 | } | |
1605 | } | |
1606 | ||
5d0a7127 | 1607 | int moira_disconnect(void) |
1608 | { | |
5d0a7127 | 1609 | |
cd9e6b16 | 1610 | if (!--mr_connections) |
5d0a7127 | 1611 | { |
cd9e6b16 | 1612 | mr_disconnect(); |
5d0a7127 | 1613 | } |
cd9e6b16 | 1614 | return 0; |
5d0a7127 | 1615 | } |
1616 | ||
5d0a7127 | 1617 | void get_distinguished_name(LDAP *ldap_handle, LDAPMessage *ldap_entry, |
cd9e6b16 | 1618 | char *distinguished_name) |
5d0a7127 | 1619 | { |
cd9e6b16 | 1620 | char *CName; |
1621 | ||
5d0a7127 | 1622 | CName = ldap_get_dn(ldap_handle, ldap_entry); |
1623 | if (CName == NULL) | |
1624 | return; | |
1625 | strcpy(distinguished_name, CName); | |
1626 | ldap_memfree(CName); | |
1627 | } | |
1628 | ||
1629 | int linklist_create_entry(char *attribute, char *value, | |
cd9e6b16 | 1630 | LK_ENTRY **linklist_entry) |
5d0a7127 | 1631 | { |
1632 | (*linklist_entry) = calloc(1, sizeof(LK_ENTRY)); | |
1633 | if (!(*linklist_entry)) | |
1634 | { | |
1635 | return(1); | |
1636 | } | |
1637 | memset((*linklist_entry), '\0', sizeof(LK_ENTRY)); | |
1638 | (*linklist_entry)->attribute = calloc(1, strlen(attribute) + 1); | |
1639 | memset((*linklist_entry)->attribute, '\0', strlen(attribute) + 1); | |
1640 | strcpy((*linklist_entry)->attribute, attribute); | |
1641 | (*linklist_entry)->value = calloc(1, strlen(value) + 1); | |
1642 | memset((*linklist_entry)->value, '\0', strlen(value) + 1); | |
1643 | strcpy((*linklist_entry)->value, value); | |
1644 | (*linklist_entry)->length = strlen(value); | |
1645 | (*linklist_entry)->next = NULL; | |
1646 | return(0); | |
1647 | } | |
1648 | ||
1649 | void print_to_screen(const char *fmt, ...) | |
1650 | { | |
1651 | va_list pvar; | |
cd9e6b16 | 1652 | |
5d0a7127 | 1653 | va_start(pvar, fmt); |
1654 | vfprintf(stderr, fmt, pvar); | |
1655 | fflush(stderr); | |
1656 | va_end(pvar); | |
1657 | } | |
cd9e6b16 | 1658 | |
1659 | int get_group_membership(char *group_membership, char *group_ou, | |
1660 | int *security_flag, char **av) | |
1661 | { | |
1662 | int maillist_flag; | |
1663 | int group_flag; | |
1664 | ||
1665 | maillist_flag = atoi(av[L_MAILLIST]); | |
1666 | group_flag = atoi(av[L_GROUP]); | |
1667 | if (security_flag != NULL) | |
1668 | (*security_flag) = 0; | |
1669 | ||
1670 | if ((maillist_flag) && (group_flag)) | |
1671 | { | |
1672 | if (group_membership != NULL) | |
1673 | group_membership[0] = 'B'; | |
1674 | if (security_flag != NULL) | |
1675 | (*security_flag) = 1; | |
1676 | if (group_ou != NULL) | |
1677 | strcpy(group_ou, group_ou_both); | |
1678 | } | |
1679 | else if ((!maillist_flag) && (group_flag)) | |
1680 | { | |
1681 | if (group_membership != NULL) | |
1682 | group_membership[0] = 'S'; | |
1683 | if (security_flag != NULL) | |
1684 | (*security_flag) = 1; | |
1685 | if (group_ou != NULL) | |
1686 | strcpy(group_ou, group_ou_security); | |
1687 | } | |
1688 | else if ((maillist_flag) && (!group_flag)) | |
1689 | { | |
1690 | if (group_membership != NULL) | |
1691 | group_membership[0] = 'D'; | |
1692 | if (group_ou != NULL) | |
1693 | strcpy(group_ou, group_ou_distribution); | |
1694 | } | |
1695 | else | |
1696 | { | |
1697 | if (group_membership != NULL) | |
1698 | group_membership[0] = 'N'; | |
1699 | if (group_ou != NULL) | |
1700 | strcpy(group_ou, group_ou_neither); | |
1701 | } | |
1702 | return(0); | |
1703 | } | |
1704 | ||
f75f605a | 1705 | int group_rename(LDAP *ldap_handle, char *dn_path, |
1706 | char *before_group_name, char *before_group_membership, | |
5a775f54 | 1707 | char *before_group_ou, int before_security_flag, char *before_desc, |
f75f605a | 1708 | char *after_group_name, char *after_group_membership, |
89db421e | 1709 | char *after_group_ou, int after_security_flag, char *after_desc, |
1710 | char *MoiraId, char *filter) | |
9db0b148 | 1711 | { |
1712 | LDAPMod *mods[20]; | |
1713 | char old_dn[512]; | |
1714 | char new_dn[512]; | |
78af4e6e | 1715 | char new_dn_path[512]; |
78af4e6e | 1716 | char sam_name[256]; |
9db0b148 | 1717 | char *attr_array[3]; |
89db421e | 1718 | char *mitMoiraId_v[] = {NULL, NULL}; |
9db0b148 | 1719 | char *name_v[] = {NULL, NULL}; |
5a775f54 | 1720 | char *desc_v[] = {NULL, NULL}; |
78af4e6e | 1721 | char *samAccountName_v[] = {NULL, NULL}; |
c76c595a | 1722 | char *groupTypeControl_v[] = {NULL, NULL}; |
1723 | u_int groupTypeControl = ADS_GROUP_TYPE_GLOBAL_GROUP; | |
1724 | char groupTypeControlStr[80]; | |
9db0b148 | 1725 | int n; |
1726 | int i; | |
1727 | int rc; | |
9db0b148 | 1728 | LK_ENTRY *group_base; |
1729 | int group_count; | |
9db0b148 | 1730 | |
f75f605a | 1731 | if (!check_string(before_group_name)) |
78af4e6e | 1732 | { |
f75f605a | 1733 | com_err(whoami, 0, "invalid LDAP list name %s", before_group_name); |
89db421e | 1734 | return(AD_INVALID_NAME); |
78af4e6e | 1735 | } |
f75f605a | 1736 | if (!check_string(after_group_name)) |
78af4e6e | 1737 | { |
f75f605a | 1738 | com_err(whoami, 0, "invalid LDAP list name %s", after_group_name); |
89db421e | 1739 | return(AD_INVALID_NAME); |
1740 | } | |
1741 | ||
1742 | group_count = 0; | |
1743 | group_base = NULL; | |
1744 | if (rc = ad_get_group(ldap_handle, dn_path, before_group_name, | |
1745 | before_group_membership, | |
1746 | MoiraId, "distinguishedName", &group_base, | |
1747 | &group_count, filter)) | |
1748 | return(rc); | |
1749 | ||
1750 | if (group_count == 0) | |
1751 | { | |
1752 | return(AD_NO_GROUPS_FOUND); | |
1753 | } | |
1754 | if (group_count != 1) | |
1755 | { | |
1756 | com_err(whoami, 0, | |
1757 | "multiple groups with MoiraId = %s exist in the AD", | |
1758 | MoiraId); | |
1759 | return(AD_MULTIPLE_GROUPS_FOUND); | |
78af4e6e | 1760 | } |
89db421e | 1761 | strcpy(old_dn, group_base->value); |
78af4e6e | 1762 | |
89db421e | 1763 | linklist_free(group_base); |
1764 | group_base = NULL; | |
1765 | group_count = 0; | |
1766 | attr_array[0] = "sAMAccountName"; | |
9db0b148 | 1767 | attr_array[1] = NULL; |
89db421e | 1768 | if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array, |
9db0b148 | 1769 | &group_base, &group_count)) != 0) |
1770 | { | |
f75f605a | 1771 | com_err(whoami, 0, "LDAP server unable to get list %s dn : %s", |
1772 | after_group_name, ldap_err2string(rc)); | |
1773 | return(rc); | |
9db0b148 | 1774 | } |
1775 | if (group_count != 1) | |
1776 | { | |
89db421e | 1777 | com_err(whoami, 0, |
1778 | "Unable to get sAMAccountName for group %s", | |
1779 | before_group_name); | |
1780 | return(AD_LDAP_FAILURE); | |
9db0b148 | 1781 | } |
89db421e | 1782 | |
1783 | strcpy(sam_name, group_base->value); | |
9db0b148 | 1784 | linklist_free(group_base); |
1785 | group_base = NULL; | |
1786 | group_count = 0; | |
1787 | ||
f75f605a | 1788 | sprintf(new_dn_path, "%s,%s", after_group_ou, dn_path); |
1789 | sprintf(new_dn, "cn=%s", after_group_name); | |
1790 | if ((rc = ldap_rename_s(ldap_handle, old_dn, new_dn, new_dn_path, | |
78af4e6e | 1791 | TRUE, NULL, NULL)) != LDAP_SUCCESS) |
1792 | { | |
f75f605a | 1793 | com_err(whoami, 0, "Couldn't rename list from %s to %s : %s", |
89db421e | 1794 | before_group_name, after_group_name, ldap_err2string(rc)); |
f75f605a | 1795 | return(rc); |
78af4e6e | 1796 | } |
9db0b148 | 1797 | |
f75f605a | 1798 | name_v[0] = after_group_name; |
c0bd7667 | 1799 | if (!strncmp(&sam_name[strlen(sam_name) - strlen("_group")], "_group", strlen("_group"))) |
89db421e | 1800 | { |
1801 | sprintf(sam_name, "%s_group", after_group_name); | |
1802 | } | |
1803 | else | |
1804 | { | |
1805 | com_err(whoami, 0, "Couldn't rename list from %s to %s : sAMAccountName not found", | |
1806 | before_group_name, after_group_name); | |
1807 | return(rc); | |
1808 | } | |
78af4e6e | 1809 | samAccountName_v[0] = sam_name; |
c76c595a | 1810 | if (after_security_flag) |
1811 | groupTypeControl |= ADS_GROUP_TYPE_SECURITY_ENABLED; | |
1812 | sprintf(groupTypeControlStr, "%ld", groupTypeControl); | |
1813 | groupTypeControl_v[0] = groupTypeControlStr; | |
9db0b148 | 1814 | n = 0; |
5a775f54 | 1815 | ADD_ATTR("samAccountName", samAccountName_v, LDAP_MOD_REPLACE); |
9db0b148 | 1816 | ADD_ATTR("displayName", name_v, LDAP_MOD_REPLACE); |
89db421e | 1817 | desc_v[0] = after_desc; |
5a775f54 | 1818 | if (strlen(after_desc) == 0) |
1819 | desc_v[0] = NULL; | |
1820 | ADD_ATTR("description", desc_v, LDAP_MOD_REPLACE); | |
89db421e | 1821 | mitMoiraId_v[0] = MoiraId; |
1822 | ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_REPLACE); | |
c76c595a | 1823 | ADD_ATTR("groupType", groupTypeControl_v, LDAP_MOD_REPLACE); |
9db0b148 | 1824 | mods[n] = NULL; |
f75f605a | 1825 | sprintf(new_dn, "cn=%s,%s,%s", after_group_name, after_group_ou, dn_path); |
1826 | if ((rc = ldap_modify_s(ldap_handle, new_dn, mods)) != LDAP_SUCCESS) | |
78af4e6e | 1827 | { |
f75f605a | 1828 | com_err(whoami, 0, "After renaming, couldn't modify list data for %s : %s", |
1829 | after_group_name, ldap_err2string(rc)); | |
78af4e6e | 1830 | } |
9db0b148 | 1831 | for (i = 0; i < n; i++) |
1832 | free(mods[i]); | |
f75f605a | 1833 | return(rc); |
9db0b148 | 1834 | } |
1835 | ||
cd9e6b16 | 1836 | int group_create(int ac, char **av, void *ptr) |
1837 | { | |
1838 | LDAPMod *mods[20]; | |
5b8457c5 | 1839 | LK_ENTRY *group_base; |
cd9e6b16 | 1840 | char new_dn[256]; |
1841 | char group_ou[256]; | |
1842 | char new_group_name[256]; | |
1843 | char sam_group_name[256]; | |
1844 | char cn_group_name[256]; | |
1845 | char *cn_v[] = {NULL, NULL}; | |
1846 | char *objectClass_v[] = {"top", "group", NULL}; | |
1847 | char info[256]; | |
1848 | char *samAccountName_v[] = {NULL, NULL}; | |
cd9e6b16 | 1849 | char *altSecurityIdentities_v[] = {NULL, NULL}; |
89db421e | 1850 | char *member_v[] = {NULL, NULL}; |
cd9e6b16 | 1851 | char *name_v[] = {NULL, NULL}; |
1852 | char *desc_v[] = {NULL, NULL}; | |
1853 | char *info_v[] = {NULL, NULL}; | |
89db421e | 1854 | char *mitMoiraId_v[] = {NULL, NULL}; |
cd9e6b16 | 1855 | char *groupTypeControl_v[] = {NULL, NULL}; |
1856 | char groupTypeControlStr[80]; | |
1857 | char group_membership[1]; | |
1858 | int i; | |
1859 | int security_flag; | |
1860 | u_int groupTypeControl = ADS_GROUP_TYPE_GLOBAL_GROUP; | |
1861 | int n; | |
1862 | int rc; | |
5b8457c5 | 1863 | int group_count; |
89db421e | 1864 | int updateGroup; |
1865 | char filter[128]; | |
cd9e6b16 | 1866 | char *attr_array[3]; |
1867 | char **call_args; | |
1868 | ||
1869 | call_args = ptr; | |
1870 | ||
cd9e6b16 | 1871 | if (!check_string(av[L_NAME])) |
78af4e6e | 1872 | { |
f75f605a | 1873 | com_err(whoami, 0, "invalid LDAP list name %s", av[L_NAME]); |
89db421e | 1874 | return(AD_INVALID_NAME); |
78af4e6e | 1875 | } |
f75f605a | 1876 | |
89db421e | 1877 | updateGroup = (int)call_args[4]; |
cd9e6b16 | 1878 | memset(group_ou, 0, sizeof(group_ou)); |
1879 | memset(group_membership, 0, sizeof(group_membership)); | |
1880 | security_flag = 0; | |
1881 | get_group_membership(group_membership, group_ou, &security_flag, av); | |
89db421e | 1882 | strcpy(new_group_name, av[L_NAME]); |
1883 | sprintf(new_dn, "cn=%s,%s,%s", new_group_name, group_ou, call_args[1]); | |
cd9e6b16 | 1884 | if (security_flag) |
1885 | groupTypeControl |= ADS_GROUP_TYPE_SECURITY_ENABLED; | |
89db421e | 1886 | |
1887 | sprintf(sam_group_name, "%s_group", av[L_NAME]); | |
cd9e6b16 | 1888 | |
89db421e | 1889 | if (!updateGroup) |
1890 | { | |
cd9e6b16 | 1891 | |
89db421e | 1892 | sprintf(groupTypeControlStr, "%ld", groupTypeControl); |
1893 | groupTypeControl_v[0] = groupTypeControlStr; | |
cd9e6b16 | 1894 | |
89db421e | 1895 | strcpy(cn_group_name, av[L_NAME]); |
cd9e6b16 | 1896 | |
89db421e | 1897 | samAccountName_v[0] = sam_group_name; |
1898 | name_v[0] = new_group_name; | |
1899 | cn_v[0] = new_group_name; | |
cd9e6b16 | 1900 | |
89db421e | 1901 | n = 0; |
1902 | ADD_ATTR("cn", cn_v, LDAP_MOD_ADD); | |
1903 | ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD); | |
1904 | ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_ADD); | |
1905 | ADD_ATTR("displayName", name_v, LDAP_MOD_ADD); | |
1906 | ADD_ATTR("name", name_v, LDAP_MOD_ADD); | |
1907 | if (strlen(av[L_DESC]) != 0) | |
1908 | { | |
1909 | desc_v[0] = av[L_DESC]; | |
1910 | ADD_ATTR("description", desc_v, LDAP_MOD_ADD); | |
1911 | } | |
1912 | ADD_ATTR("groupType", groupTypeControl_v, LDAP_MOD_ADD); | |
1913 | if (strlen(av[L_ACE_NAME]) != 0) | |
1914 | { | |
1915 | sprintf(info, "The Administrator of this list is: %s", av[L_ACE_NAME]); | |
1916 | info_v[0] = info; | |
1917 | ADD_ATTR("info", info_v, LDAP_MOD_ADD); | |
1918 | } | |
1919 | if (strlen(call_args[5]) != 0) | |
1920 | { | |
1921 | mitMoiraId_v[0] = call_args[5]; | |
1922 | ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_ADD); | |
1923 | } | |
1924 | mods[n] = NULL; | |
1925 | ||
1926 | rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL); | |
1927 | ||
1928 | for (i = 0; i < n; i++) | |
1929 | free(mods[i]); | |
1930 | if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS)) | |
1931 | { | |
1932 | com_err(whoami, 0, "Unable to create/update list %s in AD : %s", | |
1933 | av[L_NAME], ldap_err2string(rc)); | |
1934 | callback_rc = rc; | |
1935 | return(rc); | |
1936 | } | |
78af4e6e | 1937 | } |
89db421e | 1938 | if ((rc == LDAP_ALREADY_EXISTS) || (updateGroup)) |
5a775f54 | 1939 | { |
1940 | n = 0; | |
89db421e | 1941 | desc_v[0] = NULL; |
1942 | if (strlen(av[L_DESC]) != 0) | |
1943 | desc_v[0] = av[L_DESC]; | |
5a775f54 | 1944 | ADD_ATTR("description", desc_v, LDAP_MOD_REPLACE); |
89db421e | 1945 | info_v[0] = NULL; |
1946 | if (strlen(av[L_ACE_NAME]) != 0) | |
1947 | { | |
1948 | sprintf(info, "The Administrator of this list is: %s", av[L_ACE_NAME]); | |
1949 | info_v[0] = info; | |
1950 | } | |
1951 | ADD_ATTR("info", info_v, LDAP_MOD_REPLACE); | |
1952 | if (strlen(call_args[5]) != 0) | |
1953 | { | |
1954 | mitMoiraId_v[0] = call_args[5]; | |
1955 | ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_REPLACE); | |
1956 | } | |
1957 | if (!(atoi(av[L_ACTIVE]))) | |
1958 | { | |
1959 | member_v[0] = NULL; | |
1960 | ADD_ATTR("member", member_v, LDAP_MOD_REPLACE); | |
1961 | } | |
5a775f54 | 1962 | mods[n] = NULL; |
1963 | rc = ldap_modify_s((LDAP *)call_args[0], new_dn, mods); | |
1964 | for (i = 0; i < n; i++) | |
1965 | free(mods[i]); | |
1966 | } | |
89db421e | 1967 | |
1968 | sprintf(filter, "(sAMAccountName=%s)", sam_group_name); | |
1969 | if (strlen(call_args[5]) != 0) | |
6c8f12af | 1970 | sprintf(filter, "(&(objectClass=group)(mitMoiraId=%s))", call_args[5]); |
cd9e6b16 | 1971 | attr_array[0] = "objectSid"; |
1972 | attr_array[1] = NULL; | |
5b8457c5 | 1973 | group_count = 0; |
1974 | group_base = NULL; | |
89db421e | 1975 | if ((rc = linklist_build((LDAP *)call_args[0], call_args[1], filter, attr_array, |
5b8457c5 | 1976 | &group_base, &group_count)) == LDAP_SUCCESS) |
cd9e6b16 | 1977 | { |
3e586ecf | 1978 | if (group_count != 1) |
1979 | { | |
1980 | if (strlen(call_args[5]) != 0) | |
1981 | { | |
1982 | linklist_free(group_base); | |
1983 | group_count = 0; | |
1984 | group_base = NULL; | |
1985 | sprintf(filter, "(sAMAccountName=%s)", sam_group_name); | |
1986 | rc = linklist_build((LDAP *)call_args[0], call_args[1], filter, | |
1987 | attr_array, &group_base, &group_count); | |
1988 | } | |
1989 | } | |
5b8457c5 | 1990 | if (group_count == 1) |
cd9e6b16 | 1991 | { |
5b8457c5 | 1992 | (*sid_ptr) = group_base; |
cd9e6b16 | 1993 | (*sid_ptr)->member = strdup(av[L_NAME]); |
1994 | (*sid_ptr)->type = (char *)GROUPS; | |
1995 | sid_ptr = &(*sid_ptr)->next; | |
1996 | } | |
5b8457c5 | 1997 | else |
1998 | { | |
1999 | if (group_base != NULL) | |
2000 | linklist_free(group_base); | |
2001 | } | |
cd9e6b16 | 2002 | } |
5b8457c5 | 2003 | else |
2004 | { | |
2005 | if (group_base != NULL) | |
2006 | linklist_free(group_base); | |
2007 | } | |
2008 | return(LDAP_SUCCESS); | |
cd9e6b16 | 2009 | } |
2010 | ||
89db421e | 2011 | int group_delete(LDAP *ldap_handle, char *dn_path, char *group_name, |
2012 | char *group_membership, char *MoiraId) | |
cd9e6b16 | 2013 | { |
2014 | LK_ENTRY *group_base; | |
f75f605a | 2015 | char temp[512]; |
89db421e | 2016 | char filter[128]; |
cd9e6b16 | 2017 | int group_count; |
2018 | int rc; | |
2019 | ||
f75f605a | 2020 | if (!check_string(group_name)) |
78af4e6e | 2021 | { |
f75f605a | 2022 | com_err(whoami, 0, "invalid LDAP list name %s", group_name); |
89db421e | 2023 | return(AD_INVALID_NAME); |
78af4e6e | 2024 | } |
89db421e | 2025 | |
2026 | memset(filter, '\0', sizeof(filter)); | |
cd9e6b16 | 2027 | group_count = 0; |
2028 | group_base = NULL; | |
cd9e6b16 | 2029 | sprintf(temp, "%s,%s", group_ou_root, dn_path); |
89db421e | 2030 | if (rc = ad_get_group(ldap_handle, temp, group_name, |
2031 | group_membership, MoiraId, | |
2032 | "distinguishedName", &group_base, | |
2033 | &group_count, filter)) | |
2034 | return(rc); | |
2035 | ||
cd9e6b16 | 2036 | if (group_count == 1) |
78af4e6e | 2037 | { |
2038 | if ((rc = ldap_delete_s(ldap_handle, group_base->value)) != LDAP_SUCCESS) | |
2039 | { | |
f75f605a | 2040 | linklist_free(group_base); |
2041 | com_err(whoami, 0, "Unable to delete list %s from AD : %s", | |
2042 | group_name, ldap_err2string(rc)); | |
89db421e | 2043 | return(rc); |
78af4e6e | 2044 | } |
f75f605a | 2045 | linklist_free(group_base); |
78af4e6e | 2046 | } |
2047 | else | |
2048 | { | |
f75f605a | 2049 | linklist_free(group_base); |
2050 | com_err(whoami, 0, "Unable to find list %s in AD.", group_name); | |
89db421e | 2051 | return(AD_NO_GROUPS_FOUND); |
78af4e6e | 2052 | } |
f75f605a | 2053 | |
78af4e6e | 2054 | return(0); |
cd9e6b16 | 2055 | } |
2056 | ||
f75f605a | 2057 | int process_lists(int ac, char **av, void *ptr) |
cd9e6b16 | 2058 | { |
f75f605a | 2059 | int rc; |
2060 | int security_flag; | |
2061 | char group_ou[256]; | |
2062 | char group_membership[2]; | |
2063 | char **call_args; | |
cd9e6b16 | 2064 | |
2065 | call_args = ptr; | |
2066 | ||
f75f605a | 2067 | security_flag = 0; |
2068 | memset(group_ou, '\0', sizeof(group_ou)); | |
2069 | memset(group_membership, '\0', sizeof(group_membership)); | |
2070 | get_group_membership(group_membership, group_ou, &security_flag, av); | |
2071 | rc = member_add((LDAP *)call_args[0], (char *)call_args[1], av[L_NAME], | |
89db421e | 2072 | group_ou, group_membership, call_args[2], |
2073 | (char *)call_args[3], ""); | |
cd9e6b16 | 2074 | return(0); |
2075 | } | |
2076 | ||
2077 | int member_list_build(int ac, char **av, void *ptr) | |
2078 | { | |
2079 | LK_ENTRY *linklist; | |
78af4e6e | 2080 | char temp[1024]; |
cd9e6b16 | 2081 | char **call_args; |
2082 | ||
2083 | call_args = ptr; | |
2084 | ||
2085 | strcpy(temp, av[ACE_NAME]); | |
2086 | if (!check_string(temp)) | |
2087 | return(0); | |
f78c7eaf | 2088 | if (!strcmp(av[ACE_TYPE], "USER")) |
cd9e6b16 | 2089 | { |
f75f605a | 2090 | if (!((int)call_args[3] & MOIRA_USERS)) |
f78c7eaf | 2091 | return(0); |
2092 | } | |
2093 | else if (!strcmp(av[ACE_TYPE], "STRING")) | |
2094 | { | |
f75f605a | 2095 | if (!((int)call_args[3] & MOIRA_STRINGS)) |
f78c7eaf | 2096 | return(0); |
2097 | if (contact_create((LDAP *)call_args[0], call_args[1], temp, contact_ou)) | |
2098 | return(0); | |
cd9e6b16 | 2099 | } |
2100 | else if (!strcmp(av[ACE_TYPE], "LIST")) | |
2101 | { | |
f75f605a | 2102 | if (!((int)call_args[3] & MOIRA_LISTS)) |
f78c7eaf | 2103 | return(0); |
cd9e6b16 | 2104 | } |
f78c7eaf | 2105 | else if (!strcmp(av[ACE_TYPE], "KERBEROS")) |
cd9e6b16 | 2106 | { |
f75f605a | 2107 | if (!((int)call_args[3] & MOIRA_KERBEROS)) |
f78c7eaf | 2108 | return(0); |
2109 | if (contact_create((LDAP *)call_args[0], call_args[1], temp, kerberos_ou)) | |
2110 | return(0); | |
cd9e6b16 | 2111 | } |
f78c7eaf | 2112 | else |
2113 | return(0); | |
2114 | ||
cd9e6b16 | 2115 | linklist = member_base; |
2116 | while (linklist) | |
2117 | { | |
2118 | if (!strcasecmp(temp, linklist->member)) | |
2119 | return(0); | |
2120 | linklist = linklist->next; | |
2121 | } | |
2122 | linklist = calloc(1, sizeof(LK_ENTRY)); | |
2123 | linklist->op = 1; | |
2124 | linklist->dn = NULL; | |
2125 | linklist->list = calloc(1, strlen(call_args[2]) + 1); | |
2126 | strcpy(linklist->list, call_args[2]); | |
2127 | linklist->type = calloc(1, strlen(av[ACE_TYPE]) + 1); | |
2128 | strcpy(linklist->type, av[ACE_TYPE]); | |
2129 | linklist->member = calloc(1, strlen(temp) + 1); | |
2130 | strcpy(linklist->member, temp); | |
2131 | linklist->next = member_base; | |
2132 | member_base = linklist; | |
2133 | return(0); | |
2134 | } | |
2135 | ||
78af4e6e | 2136 | int member_remove(LDAP *ldap_handle, char *dn_path, char *group_name, |
f75f605a | 2137 | char *group_ou, char *group_membership, char *user_name, |
89db421e | 2138 | char *UserOu, char *MoiraId) |
78af4e6e | 2139 | { |
2140 | char distinguished_name[1024]; | |
f75f605a | 2141 | char *modvalues[2]; |
78af4e6e | 2142 | char temp[256]; |
89db421e | 2143 | char filter[128]; |
78af4e6e | 2144 | int group_count; |
2145 | int i; | |
2146 | int n; | |
2147 | LDAPMod *mods[20]; | |
2148 | LK_ENTRY *group_base; | |
2149 | ULONG rc; | |
2150 | ||
2151 | if (!check_string(group_name)) | |
89db421e | 2152 | return(AD_INVALID_NAME); |
2153 | ||
2154 | memset(filter, '\0', sizeof(filter)); | |
2155 | group_base = NULL; | |
2156 | group_count = 0; | |
2157 | if (rc = ad_get_group(ldap_handle, dn_path, group_name, | |
2158 | group_membership, MoiraId, | |
2159 | "distinguishedName", &group_base, | |
2160 | &group_count, filter)) | |
2161 | return(rc); | |
2162 | ||
78af4e6e | 2163 | if (group_count != 1) |
2164 | { | |
f75f605a | 2165 | com_err(whoami, 0, "LDAP server unable to find list %s in AD", |
2166 | group_name); | |
2167 | linklist_free(group_base); | |
2168 | group_base = NULL; | |
2169 | group_count = 0; | |
78af4e6e | 2170 | goto cleanup; |
2171 | } | |
2172 | strcpy(distinguished_name, group_base->value); | |
2173 | linklist_free(group_base); | |
2174 | group_base = NULL; | |
2175 | group_count = 0; | |
78af4e6e | 2176 | |
f75f605a | 2177 | sprintf(temp, "CN=%s,%s,%s", user_name, UserOu, dn_path); |
2178 | modvalues[0] = temp; | |
2179 | modvalues[1] = NULL; | |
2180 | ||
2181 | n = 0; | |
2182 | ADD_ATTR("member", modvalues, LDAP_MOD_DELETE); | |
2183 | mods[n] = NULL; | |
2184 | rc = ldap_modify_s(ldap_handle, distinguished_name, mods); | |
2185 | for (i = 0; i < n; i++) | |
2186 | free(mods[i]); | |
6c8f12af | 2187 | if (rc == LDAP_UNWILLING_TO_PERFORM) |
2188 | rc = LDAP_SUCCESS; | |
f75f605a | 2189 | if (rc != LDAP_SUCCESS) |
78af4e6e | 2190 | { |
f75f605a | 2191 | com_err(whoami, 0, "LDAP server unable to modify list %s members : %s", |
2192 | group_name, ldap_err2string(rc)); | |
2193 | goto cleanup; | |
78af4e6e | 2194 | } |
2195 | ||
2196 | cleanup: | |
78af4e6e | 2197 | return(rc); |
2198 | } | |
2199 | ||
f75f605a | 2200 | int member_add(LDAP *ldap_handle, char *dn_path, char *group_name, |
89db421e | 2201 | char *group_ou, char *group_membership, char *user_name, |
2202 | char *UserOu, char *MoiraId) | |
cd9e6b16 | 2203 | { |
2204 | char distinguished_name[1024]; | |
f75f605a | 2205 | char *modvalues[2]; |
cd9e6b16 | 2206 | char temp[256]; |
89db421e | 2207 | char filter[128]; |
cd9e6b16 | 2208 | int group_count; |
cd9e6b16 | 2209 | int n; |
f75f605a | 2210 | int i; |
cd9e6b16 | 2211 | LDAPMod *mods[20]; |
2212 | LK_ENTRY *group_base; | |
cd9e6b16 | 2213 | ULONG rc; |
2214 | ||
89db421e | 2215 | if (!check_string(group_name)) |
2216 | return(AD_INVALID_NAME); | |
2217 | ||
cd9e6b16 | 2218 | rc = 0; |
89db421e | 2219 | memset(filter, '\0', sizeof(filter)); |
cd9e6b16 | 2220 | group_base = NULL; |
2221 | group_count = 0; | |
89db421e | 2222 | if (rc = ad_get_group(ldap_handle, dn_path, group_name, |
2223 | group_membership, MoiraId, | |
2224 | "distinguishedName", &group_base, | |
2225 | &group_count, filter)) | |
2226 | return(rc); | |
cd9e6b16 | 2227 | |
cd9e6b16 | 2228 | if (group_count != 1) |
2229 | { | |
f75f605a | 2230 | linklist_free(group_base); |
2231 | group_base = NULL; | |
2232 | group_count = 0; | |
2233 | com_err(whoami, 0, "LDAP server unable to find list %s in AD", | |
2234 | group_name); | |
89db421e | 2235 | return(AD_MULTIPLE_GROUPS_FOUND); |
cd9e6b16 | 2236 | } |
f75f605a | 2237 | |
cd9e6b16 | 2238 | strcpy(distinguished_name, group_base->value); |
2239 | linklist_free(group_base); | |
2240 | group_base = NULL; | |
2241 | group_count = 0; | |
2242 | ||
f75f605a | 2243 | sprintf(temp, "CN=%s,%s,%s", user_name, UserOu, dn_path); |
2244 | modvalues[0] = temp; | |
2245 | modvalues[1] = NULL; | |
cd9e6b16 | 2246 | |
f75f605a | 2247 | n = 0; |
2248 | ADD_ATTR("member", modvalues, LDAP_MOD_ADD); | |
2249 | mods[n] = NULL; | |
2250 | rc = ldap_modify_s(ldap_handle, distinguished_name, mods); | |
2251 | if (rc == LDAP_ALREADY_EXISTS) | |
2252 | rc = LDAP_SUCCESS; | |
89db421e | 2253 | if ((!strcmp(UserOu, contact_ou)) || (!strcmp(UserOu, kerberos_ou))) |
2254 | { | |
2255 | if (rc == LDAP_UNWILLING_TO_PERFORM) | |
2256 | rc = LDAP_SUCCESS; | |
2257 | } | |
f75f605a | 2258 | for (i = 0; i < n; i++) |
2259 | free(mods[i]); | |
2260 | if (rc != LDAP_SUCCESS) | |
cd9e6b16 | 2261 | { |
89db421e | 2262 | com_err(whoami, 0, "LDAP server unable to add %s to list %s as a member : %s", |
2263 | user_name, group_name, ldap_err2string(rc)); | |
cd9e6b16 | 2264 | } |
2265 | ||
f75f605a | 2266 | return(rc); |
cd9e6b16 | 2267 | } |
2268 | ||
2269 | int contact_create(LDAP *ld, char *bind_path, char *user, char *group_ou) | |
2270 | { | |
2271 | LDAPMod *mods[20]; | |
2272 | char new_dn[256]; | |
2273 | char cn_user_name[256]; | |
2274 | char contact_name[256]; | |
f78c7eaf | 2275 | char *email_v[] = {NULL, NULL}; |
cd9e6b16 | 2276 | char *cn_v[] = {NULL, NULL}; |
2277 | char *contact_v[] = {NULL, NULL}; | |
2278 | char *objectClass_v[] = {"top", "person", | |
2279 | "organizationalPerson", | |
2280 | "contact", NULL}; | |
2281 | char *name_v[] = {NULL, NULL}; | |
2282 | char *desc_v[] = {NULL, NULL}; | |
2283 | int n; | |
2284 | int rc; | |
2285 | int i; | |
2286 | ||
2287 | if (!check_string(user)) | |
78af4e6e | 2288 | { |
f75f605a | 2289 | com_err(whoami, 0, "invalid LDAP name %s", user); |
89db421e | 2290 | return(AD_INVALID_NAME); |
78af4e6e | 2291 | } |
cd9e6b16 | 2292 | strcpy(contact_name, user); |
2293 | sprintf(cn_user_name,"CN=%s,%s,%s", contact_name, group_ou, bind_path); | |
2294 | cn_v[0] = cn_user_name; | |
2295 | contact_v[0] = contact_name; | |
2296 | name_v[0] = user; | |
2297 | desc_v[0] = "Auto account created by Moira"; | |
f78c7eaf | 2298 | email_v[0] = user; |
cd9e6b16 | 2299 | |
2300 | strcpy(new_dn, cn_user_name); | |
2301 | n = 0; | |
2302 | ADD_ATTR("cn", contact_v, LDAP_MOD_ADD); | |
2303 | ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD); | |
2304 | ADD_ATTR("name", name_v, LDAP_MOD_ADD); | |
2305 | ADD_ATTR("displayName", name_v, LDAP_MOD_ADD); | |
2306 | ADD_ATTR("description", desc_v, LDAP_MOD_ADD); | |
f78c7eaf | 2307 | if (!strcmp(group_ou, contact_ou)) |
2308 | { | |
2309 | ADD_ATTR("mail", email_v, LDAP_MOD_ADD); | |
2310 | } | |
cd9e6b16 | 2311 | mods[n] = NULL; |
2312 | ||
2313 | rc = ldap_add_ext_s(ld, new_dn, mods, NULL, NULL); | |
2314 | for (i = 0; i < n; i++) | |
2315 | free(mods[i]); | |
f78c7eaf | 2316 | if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS)) |
2317 | { | |
2318 | n = 0; | |
2319 | ADD_ATTR("cn", contact_v, LDAP_MOD_ADD); | |
2320 | ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD); | |
2321 | ADD_ATTR("name", name_v, LDAP_MOD_ADD); | |
2322 | ADD_ATTR("displayName", name_v, LDAP_MOD_ADD); | |
2323 | ADD_ATTR("description", desc_v, LDAP_MOD_ADD); | |
2324 | mods[n] = NULL; | |
2325 | rc = ldap_add_ext_s(ld, new_dn, mods, NULL, NULL); | |
2326 | for (i = 0; i < n; i++) | |
2327 | free(mods[i]); | |
2328 | } | |
cd9e6b16 | 2329 | if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS)) |
78af4e6e | 2330 | { |
f75f605a | 2331 | com_err(whoami, 0, "could not create contact %s : %s", |
2332 | user, ldap_err2string(rc)); | |
89db421e | 2333 | return(rc); |
78af4e6e | 2334 | } |
2335 | return(0); | |
2336 | } | |
2337 | ||
f75f605a | 2338 | int user_update(LDAP *ldap_handle, char *dn_path, char *user_name, |
89db421e | 2339 | char *Uid, char *MitId, char *MoiraId, int State) |
78af4e6e | 2340 | { |
2341 | LDAPMod *mods[20]; | |
2342 | LK_ENTRY *group_base; | |
2343 | int group_count; | |
2344 | char distinguished_name[256]; | |
89db421e | 2345 | char *mitMoiraId_v[] = {NULL, NULL}; |
78af4e6e | 2346 | char *uid_v[] = {NULL, NULL}; |
2347 | char *mitid_v[] = {NULL, NULL}; | |
f78c7eaf | 2348 | char *homedir_v[] = {NULL, NULL}; |
2349 | char *winProfile_v[] = {NULL, NULL}; | |
2350 | char *drives_v[] = {NULL, NULL}; | |
89db421e | 2351 | char *userAccountControl_v[] = {NULL, NULL}; |
2352 | char userAccountControlStr[80]; | |
78af4e6e | 2353 | int n; |
2354 | int rc; | |
2355 | int i; | |
65382c46 | 2356 | int last_weight; |
89db421e | 2357 | u_int userAccountControl = UF_NORMAL_ACCOUNT | UF_DONT_EXPIRE_PASSWD | UF_PASSWD_CANT_CHANGE; |
2358 | char filter[128]; | |
78af4e6e | 2359 | char *attr_array[3]; |
65382c46 | 2360 | char cWeight[3]; |
f78c7eaf | 2361 | char **hp; |
2362 | char path[256]; | |
65382c46 | 2363 | char cPath[256]; |
c0bd7667 | 2364 | char temp[256]; |
f78c7eaf | 2365 | char winPath[256]; |
2366 | char winProfile[256]; | |
78af4e6e | 2367 | |
f75f605a | 2368 | if (!check_string(user_name)) |
78af4e6e | 2369 | { |
f75f605a | 2370 | com_err(whoami, 0, "invalid LDAP user name %s", user_name); |
89db421e | 2371 | return(AD_INVALID_NAME); |
78af4e6e | 2372 | } |
2373 | ||
78af4e6e | 2374 | group_count = 0; |
2375 | group_base = NULL; | |
89db421e | 2376 | |
2377 | if (strlen(MoiraId) != 0) | |
78af4e6e | 2378 | { |
c0bd7667 | 2379 | sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId); |
89db421e | 2380 | attr_array[0] = "cn"; |
2381 | attr_array[1] = NULL; | |
2382 | if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array, | |
2383 | &group_base, &group_count)) != 0) | |
2384 | { | |
2385 | com_err(whoami, 0, "LDAP server couldn't process user %s : %s", | |
2386 | user_name, ldap_err2string(rc)); | |
2387 | return(rc); | |
2388 | } | |
2389 | } | |
c0bd7667 | 2390 | if (group_count != 1) |
89db421e | 2391 | { |
c0bd7667 | 2392 | linklist_free(group_base); |
2393 | group_base = NULL; | |
2394 | group_count = 0; | |
89db421e | 2395 | sprintf(filter, "(sAMAccountName=%s)", user_name); |
2396 | attr_array[0] = "cn"; | |
2397 | attr_array[1] = NULL; | |
c0bd7667 | 2398 | sprintf(temp, "%s,%s", user_ou, dn_path); |
2399 | if ((rc = linklist_build(ldap_handle, temp, filter, attr_array, | |
89db421e | 2400 | &group_base, &group_count)) != 0) |
2401 | { | |
2402 | com_err(whoami, 0, "LDAP server couldn't process user %s : %s", | |
2403 | user_name, ldap_err2string(rc)); | |
2404 | return(rc); | |
2405 | } | |
78af4e6e | 2406 | } |
2407 | ||
2408 | if (group_count != 1) | |
2409 | { | |
f75f605a | 2410 | com_err(whoami, 0, "LDAP server unable to find user %s in AD", |
2411 | user_name); | |
2412 | linklist_free(group_base); | |
89db421e | 2413 | return(AD_NO_USER_FOUND); |
78af4e6e | 2414 | } |
2415 | strcpy(distinguished_name, group_base->dn); | |
2416 | ||
f75f605a | 2417 | linklist_free(group_base); |
2418 | group_count = 0; | |
78af4e6e | 2419 | n = 0; |
f78c7eaf | 2420 | if ((hp = hes_resolve(user_name, "filsys")) != NULL) |
2421 | { | |
65382c46 | 2422 | memset(cWeight, 0, sizeof(cWeight)); |
2423 | memset(cPath, 0, sizeof(cPath)); | |
f78c7eaf | 2424 | memset(path, 0, sizeof(path)); |
2425 | memset(winPath, 0, sizeof(winPath)); | |
65382c46 | 2426 | last_weight = 1000; |
2427 | i = 0; | |
2428 | while (hp[i] != NULL) | |
f78c7eaf | 2429 | { |
7863a0af | 2430 | if (sscanf(hp[i], "%*s %s", cPath)) |
65382c46 | 2431 | { |
7863a0af | 2432 | if (strnicmp(cPath, AFS, strlen(AFS)) == 0) |
65382c46 | 2433 | { |
7863a0af | 2434 | if (sscanf(hp[i], "%*s %*s %*s %*s %s", cWeight)) |
2435 | { | |
2436 | if (atoi(cWeight) < last_weight) | |
2437 | { | |
2438 | strcpy(path, cPath); | |
2439 | last_weight = (int)atoi(cWeight); | |
2440 | } | |
2441 | } | |
2442 | else | |
2443 | strcpy(path, cPath); | |
2444 | } | |
65382c46 | 2445 | } |
2446 | ++i; | |
2447 | } | |
2448 | if (strlen(path)) | |
2449 | { | |
2450 | if (!strnicmp(path, AFS, strlen(AFS))) | |
2451 | { | |
2452 | AfsToWinAfs(path, winPath); | |
2453 | homedir_v[0] = winPath; | |
2454 | ADD_ATTR("homeDirectory", homedir_v, LDAP_MOD_REPLACE); | |
2455 | strcpy(winProfile, winPath); | |
2456 | strcat(winProfile, "\\.winprofile"); | |
2457 | winProfile_v[0] = winProfile; | |
2458 | ADD_ATTR("profilePath", winProfile_v, LDAP_MOD_REPLACE); | |
2459 | drives_v[0] = "H:"; | |
2460 | ADD_ATTR("homeDrive", drives_v, LDAP_MOD_REPLACE); | |
2461 | } | |
f78c7eaf | 2462 | } |
2463 | } | |
89db421e | 2464 | uid_v[0] = Uid; |
2465 | if (strlen(Uid) == 0) | |
2466 | uid_v[0] = NULL; | |
2467 | ADD_ATTR("uid", uid_v, LDAP_MOD_REPLACE); | |
2468 | ADD_ATTR("uidNumber", uid_v, LDAP_MOD_REPLACE); | |
2469 | mitid_v[0] = MitId; | |
2470 | if (strlen(MitId) == 0) | |
2471 | mitid_v[0] = NULL; | |
2472 | ADD_ATTR("employeeID", mitid_v, LDAP_MOD_REPLACE); | |
2473 | mitMoiraId_v[0] = MoiraId; | |
2474 | if (strlen(MoiraId) == 0) | |
2475 | mitMoiraId_v[0] = NULL; | |
2476 | ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_REPLACE); | |
2477 | if ((State != US_NO_PASSWD) && (State != US_REGISTERED)) | |
2478 | userAccountControl |= UF_ACCOUNTDISABLE; | |
2479 | sprintf(userAccountControlStr, "%ld", userAccountControl); | |
2480 | userAccountControl_v[0] = userAccountControlStr; | |
2481 | ADD_ATTR("userAccountControl", userAccountControl_v, LDAP_MOD_REPLACE); | |
78af4e6e | 2482 | mods[n] = NULL; |
89db421e | 2483 | if ((rc = ldap_modify_s(ldap_handle, distinguished_name, mods)) != LDAP_SUCCESS) |
78af4e6e | 2484 | { |
89db421e | 2485 | com_err(whoami, 0, "Couldn't modify user data for %s : %s", |
2486 | user_name, ldap_err2string(rc)); | |
78af4e6e | 2487 | } |
89db421e | 2488 | for (i = 0; i < n; i++) |
2489 | free(mods[i]); | |
2490 | ||
f78c7eaf | 2491 | if (hp != NULL) |
2492 | { | |
2493 | i = 0; | |
2494 | while (hp[i]) | |
2495 | { | |
2496 | free(hp[i]); | |
2497 | i++; | |
2498 | } | |
2499 | } | |
78af4e6e | 2500 | |
f75f605a | 2501 | return(rc); |
cd9e6b16 | 2502 | } |
2503 | ||
f75f605a | 2504 | int user_rename(LDAP *ldap_handle, char *dn_path, char *before_user_name, |
89db421e | 2505 | char *user_name) |
9db0b148 | 2506 | { |
2507 | LDAPMod *mods[20]; | |
2508 | char new_dn[256]; | |
2509 | char old_dn[256]; | |
9db0b148 | 2510 | char upn[256]; |
2511 | char temp[128]; | |
2512 | char *userPrincipalName_v[] = {NULL, NULL}; | |
2513 | char *altSecurityIdentities_v[] = {NULL, NULL}; | |
2514 | char *name_v[] = {NULL, NULL}; | |
78af4e6e | 2515 | char *samAccountName_v[] = {NULL, NULL}; |
9db0b148 | 2516 | int n; |
2517 | int rc; | |
2518 | int i; | |
9db0b148 | 2519 | |
f75f605a | 2520 | if (!check_string(before_user_name)) |
78af4e6e | 2521 | { |
f75f605a | 2522 | com_err(whoami, 0, "invalid LDAP user name %s", before_user_name); |
89db421e | 2523 | return(AD_INVALID_NAME); |
78af4e6e | 2524 | } |
f75f605a | 2525 | if (!check_string(user_name)) |
78af4e6e | 2526 | { |
f75f605a | 2527 | com_err(whoami, 0, "invalid LDAP user name %s", user_name); |
89db421e | 2528 | return(AD_INVALID_NAME); |
78af4e6e | 2529 | } |
9db0b148 | 2530 | |
f75f605a | 2531 | strcpy(user_name, user_name); |
2532 | sprintf(old_dn, "cn=%s,%s,%s", before_user_name, user_ou, dn_path); | |
9db0b148 | 2533 | sprintf(new_dn, "cn=%s", user_name); |
f75f605a | 2534 | if ((rc = ldap_rename_s(ldap_handle, old_dn, new_dn, NULL, TRUE, |
9db0b148 | 2535 | NULL, NULL)) != LDAP_SUCCESS) |
2536 | { | |
89db421e | 2537 | com_err(whoami, 0, "Couldn't rename user from %s to %s : %s", |
2538 | before_user_name, user_name, ldap_err2string(rc)); | |
f75f605a | 2539 | return(rc); |
9db0b148 | 2540 | } |
2541 | ||
2542 | name_v[0] = user_name; | |
2543 | sprintf(upn, "%s@%s", user_name, ldap_domain); | |
2544 | userPrincipalName_v[0] = upn; | |
2545 | sprintf(temp, "Kerberos:%s@%s", user_name, PRIMARY_REALM); | |
2546 | altSecurityIdentities_v[0] = temp; | |
78af4e6e | 2547 | samAccountName_v[0] = user_name; |
9db0b148 | 2548 | |
2549 | n = 0; | |
2550 | ADD_ATTR("altSecurityIdentities", altSecurityIdentities_v, LDAP_MOD_REPLACE); | |
2551 | ADD_ATTR("userPrincipalName", userPrincipalName_v, LDAP_MOD_REPLACE); | |
2552 | ADD_ATTR("displayName", name_v, LDAP_MOD_REPLACE); | |
78af4e6e | 2553 | ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_REPLACE); |
9db0b148 | 2554 | mods[n] = NULL; |
f75f605a | 2555 | sprintf(new_dn, "cn=%s,%s,%s", user_name, user_ou, dn_path); |
2556 | if ((rc = ldap_modify_s(ldap_handle, new_dn, mods)) != LDAP_SUCCESS) | |
9db0b148 | 2557 | { |
f75f605a | 2558 | com_err(whoami, 0, "After renaming, couldn't modify user data for %s : %s", |
2559 | user_name, ldap_err2string(rc)); | |
9db0b148 | 2560 | } |
2561 | for (i = 0; i < n; i++) | |
2562 | free(mods[i]); | |
f75f605a | 2563 | return(rc); |
9db0b148 | 2564 | } |
2565 | ||
f75f605a | 2566 | int filesys_process(LDAP *ldap_handle, char *dn_path, char *fs_name, |
2567 | char *fs_type, char *fs_pack, int operation) | |
f78c7eaf | 2568 | { |
2569 | char distinguished_name[256]; | |
2570 | char winPath[256]; | |
2571 | char winProfile[256]; | |
89db421e | 2572 | char filter[128]; |
f78c7eaf | 2573 | char *attr_array[3]; |
2574 | char *homedir_v[] = {NULL, NULL}; | |
2575 | char *winProfile_v[] = {NULL, NULL}; | |
2576 | char *drives_v[] = {NULL, NULL}; | |
f78c7eaf | 2577 | int group_count; |
2578 | int n; | |
2579 | int rc; | |
2580 | int i; | |
f78c7eaf | 2581 | LDAPMod *mods[20]; |
2582 | LK_ENTRY *group_base; | |
2583 | ||
f75f605a | 2584 | if (!check_string(fs_name)) |
f78c7eaf | 2585 | { |
f75f605a | 2586 | com_err(whoami, 0, "invalid filesys name %s", fs_name); |
89db421e | 2587 | return(AD_INVALID_NAME); |
f78c7eaf | 2588 | } |
2589 | ||
f75f605a | 2590 | if (strcmp(fs_type, "AFS")) |
f78c7eaf | 2591 | { |
f75f605a | 2592 | com_err(whoami, 0, "invalid filesys type %s", fs_type); |
89db421e | 2593 | return(AD_INVALID_FILESYS); |
f78c7eaf | 2594 | } |
2595 | ||
f78c7eaf | 2596 | group_count = 0; |
2597 | group_base = NULL; | |
89db421e | 2598 | sprintf(filter, "(sAMAccountName=%s)", fs_name); |
f78c7eaf | 2599 | attr_array[0] = "cn"; |
2600 | attr_array[1] = NULL; | |
89db421e | 2601 | if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array, |
f78c7eaf | 2602 | &group_base, &group_count)) != 0) |
2603 | { | |
f75f605a | 2604 | com_err(whoami, 0, "LDAP server couldn't process filesys %s : %s", |
2605 | fs_name, ldap_err2string(rc)); | |
2606 | return(rc); | |
f78c7eaf | 2607 | } |
2608 | ||
2609 | if (group_count != 1) | |
2610 | { | |
f75f605a | 2611 | linklist_free(group_base); |
2612 | com_err(whoami, 0, "LDAP server unable to find user %s in AD", | |
2613 | fs_name); | |
2614 | return(LDAP_NO_SUCH_OBJECT); | |
f78c7eaf | 2615 | } |
2616 | strcpy(distinguished_name, group_base->dn); | |
f75f605a | 2617 | linklist_free(group_base); |
2618 | group_count = 0; | |
f78c7eaf | 2619 | |
2620 | n = 0; | |
2621 | if (operation == LDAP_MOD_ADD) | |
2622 | { | |
2623 | memset(winPath, 0, sizeof(winPath)); | |
f75f605a | 2624 | AfsToWinAfs(fs_pack, winPath); |
f78c7eaf | 2625 | homedir_v[0] = winPath; |
2626 | drives_v[0] = "H:"; | |
2627 | memset(winProfile, 0, sizeof(winProfile)); | |
2628 | strcpy(winProfile, winPath); | |
2629 | strcat(winProfile, "\\.winprofile"); | |
2630 | winProfile_v[0] = winProfile; | |
2631 | } | |
2632 | else | |
2633 | { | |
2634 | homedir_v[0] = NULL; | |
2635 | drives_v[0] = NULL; | |
2636 | winProfile_v[0] = NULL; | |
2637 | } | |
2638 | ADD_ATTR("profilePath", winProfile_v, operation); | |
2639 | ADD_ATTR("homeDrive", drives_v, operation); | |
2640 | ADD_ATTR("homeDirectory", homedir_v, operation); | |
2641 | mods[n] = NULL; | |
2642 | ||
f75f605a | 2643 | rc = ldap_modify_s(ldap_handle, distinguished_name, mods); |
f78c7eaf | 2644 | if (rc != LDAP_SUCCESS) |
2645 | { | |
f75f605a | 2646 | com_err(whoami, 0, "Couldn't modify user data for filesys %s : %s", |
2647 | fs_name, ldap_err2string(rc)); | |
f78c7eaf | 2648 | } |
2649 | for (i = 0; i < n; i++) | |
2650 | free(mods[i]); | |
2651 | ||
f75f605a | 2652 | return(rc); |
f78c7eaf | 2653 | } |
2654 | ||
cd9e6b16 | 2655 | int user_create(int ac, char **av, void *ptr) |
2656 | { | |
5b8457c5 | 2657 | LK_ENTRY *group_base; |
cd9e6b16 | 2658 | LDAPMod *mods[20]; |
2659 | char new_dn[256]; | |
2660 | char user_name[256]; | |
9db0b148 | 2661 | char sam_name[256]; |
5b8457c5 | 2662 | char upn[256]; |
cd9e6b16 | 2663 | char *cn_v[] = {NULL, NULL}; |
2664 | char *objectClass_v[] = {"top", "person", | |
2665 | "organizationalPerson", | |
2666 | "user", NULL}; | |
2667 | ||
2668 | char *samAccountName_v[] = {NULL, NULL}; | |
2669 | char *altSecurityIdentities_v[] = {NULL, NULL}; | |
89db421e | 2670 | char *mitMoiraId_v[] = {NULL, NULL}; |
cd9e6b16 | 2671 | char *name_v[] = {NULL, NULL}; |
2672 | char *desc_v[] = {NULL, NULL}; | |
cd9e6b16 | 2673 | char *userPrincipalName_v[] = {NULL, NULL}; |
2674 | char *userAccountControl_v[] = {NULL, NULL}; | |
78af4e6e | 2675 | char *uid_v[] = {NULL, NULL}; |
2676 | char *mitid_v[] = {NULL, NULL}; | |
cd9e6b16 | 2677 | char userAccountControlStr[80]; |
2678 | char temp[128]; | |
2679 | u_int userAccountControl = UF_NORMAL_ACCOUNT | UF_DONT_EXPIRE_PASSWD | UF_PASSWD_CANT_CHANGE; | |
2680 | int n; | |
2681 | int rc; | |
2682 | int i; | |
5b8457c5 | 2683 | int group_count; |
89db421e | 2684 | char filter[128]; |
cd9e6b16 | 2685 | char *attr_array[3]; |
2686 | char **call_args; | |
2687 | ||
2688 | call_args = ptr; | |
2689 | ||
78af4e6e | 2690 | if (!check_string(av[U_NAME])) |
2691 | { | |
89db421e | 2692 | callback_rc = AD_INVALID_NAME; |
f75f605a | 2693 | com_err(whoami, 0, "invalid LDAP user name %s", av[U_NAME]); |
89db421e | 2694 | return(AD_INVALID_NAME); |
78af4e6e | 2695 | } |
9db0b148 | 2696 | |
cd9e6b16 | 2697 | strcpy(user_name, av[U_NAME]); |
2698 | sprintf(upn, "%s@%s", user_name, ldap_domain); | |
78af4e6e | 2699 | sprintf(sam_name, "%s", av[U_NAME]); |
9db0b148 | 2700 | samAccountName_v[0] = sam_name; |
89db421e | 2701 | if ((atoi(av[U_STATE]) != US_NO_PASSWD) && (atoi(av[U_STATE]) != US_REGISTERED)) |
cd9e6b16 | 2702 | userAccountControl |= UF_ACCOUNTDISABLE; |
2703 | sprintf(userAccountControlStr, "%ld", userAccountControl); | |
2704 | userAccountControl_v[0] = userAccountControlStr; | |
2705 | userPrincipalName_v[0] = upn; | |
2706 | ||
2707 | cn_v[0] = user_name; | |
2708 | name_v[0] = user_name; | |
2709 | desc_v[0] = "Auto account created by Moira"; | |
2710 | sprintf(temp, "Kerberos:%s@%s", user_name, PRIMARY_REALM); | |
2711 | altSecurityIdentities_v[0] = temp; | |
2712 | sprintf(new_dn, "cn=%s,%s,%s", user_name, user_ou, call_args[1]); | |
2713 | ||
2714 | n = 0; | |
2715 | ADD_ATTR("cn", cn_v, LDAP_MOD_ADD); | |
2716 | ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD); | |
2717 | ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_ADD); | |
2718 | ADD_ATTR("userPrincipalName", userPrincipalName_v, LDAP_MOD_ADD); | |
2719 | ADD_ATTR("userAccountControl", userAccountControl_v, LDAP_MOD_ADD); | |
2720 | ADD_ATTR("name", name_v, LDAP_MOD_ADD); | |
2721 | ADD_ATTR("displayName", name_v, LDAP_MOD_ADD); | |
2722 | ADD_ATTR("description", desc_v, LDAP_MOD_ADD); | |
89db421e | 2723 | if (strlen(call_args[2]) != 0) |
2724 | { | |
2725 | mitMoiraId_v[0] = call_args[2]; | |
2726 | ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_ADD); | |
2727 | } | |
cd9e6b16 | 2728 | ADD_ATTR("altSecurityIdentities", altSecurityIdentities_v, LDAP_MOD_ADD); |
78af4e6e | 2729 | if (strlen(av[U_UID]) != 0) |
2730 | { | |
2731 | uid_v[0] = av[U_UID]; | |
2732 | ADD_ATTR("uid", uid_v, LDAP_MOD_ADD); | |
2733 | ADD_ATTR("uidNumber", uid_v, LDAP_MOD_ADD); | |
2734 | } | |
2735 | if (strlen(av[U_MITID]) != 0) | |
2736 | mitid_v[0] = av[U_MITID]; | |
2737 | else | |
2738 | mitid_v[0] = "none"; | |
2739 | ADD_ATTR("employeeID", mitid_v, LDAP_MOD_ADD); | |
cd9e6b16 | 2740 | mods[n] = NULL; |
2741 | ||
2742 | rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL); | |
78af4e6e | 2743 | for (i = 0; i < n; i++) |
2744 | free(mods[i]); | |
5b8457c5 | 2745 | if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS)) |
2746 | { | |
2747 | com_err(whoami, 0, "could not create user %s : %s", | |
2748 | user_name, ldap_err2string(rc)); | |
2749 | callback_rc = rc; | |
2750 | return(rc); | |
2751 | } | |
cd9e6b16 | 2752 | if (rc == LDAP_SUCCESS) |
2753 | { | |
f78c7eaf | 2754 | if ((rc = set_password(sam_name, "", ldap_domain)) != 0) |
cd9e6b16 | 2755 | { |
f75f605a | 2756 | com_err(whoami, 0, "Couldn't set password for user %s : %ld", |
2757 | user_name, rc); | |
cd9e6b16 | 2758 | } |
2759 | } | |
89db421e | 2760 | sprintf(filter, "(sAMAccountName=%s)", av[U_NAME]); |
2761 | if (strlen(call_args[2]) != 0) | |
c0bd7667 | 2762 | sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", call_args[2]); |
cd9e6b16 | 2763 | attr_array[0] = "objectSid"; |
2764 | attr_array[1] = NULL; | |
5b8457c5 | 2765 | group_count = 0; |
2766 | group_base = NULL; | |
89db421e | 2767 | if ((rc = linklist_build((LDAP *)call_args[0], call_args[1], filter, attr_array, |
5b8457c5 | 2768 | &group_base, &group_count)) == LDAP_SUCCESS) |
cd9e6b16 | 2769 | { |
3e586ecf | 2770 | if (group_count != 1) |
2771 | { | |
2772 | if (strlen(call_args[2]) != 0) | |
2773 | { | |
2774 | linklist_free(group_base); | |
2775 | group_count = 0; | |
2776 | group_base = NULL; | |
2777 | sprintf(filter, "(sAMAccountName=%s)", av[U_NAME]); | |
2778 | rc = linklist_build((LDAP *)call_args[0], call_args[1], filter, | |
2779 | attr_array, &group_base, &group_count); | |
2780 | } | |
2781 | } | |
5b8457c5 | 2782 | if (group_count == 1) |
cd9e6b16 | 2783 | { |
5b8457c5 | 2784 | (*sid_ptr) = group_base; |
3e586ecf | 2785 | (*sid_ptr)->member = strdup(av[U_NAME]); |
5b8457c5 | 2786 | (*sid_ptr)->type = (char *)GROUPS; |
cd9e6b16 | 2787 | sid_ptr = &(*sid_ptr)->next; |
2788 | } | |
5b8457c5 | 2789 | else |
2790 | { | |
2791 | if (group_base != NULL) | |
2792 | linklist_free(group_base); | |
2793 | } | |
2794 | } | |
2795 | else | |
2796 | { | |
2797 | if (group_base != NULL) | |
2798 | linklist_free(group_base); | |
cd9e6b16 | 2799 | } |
78af4e6e | 2800 | return(0); |
cd9e6b16 | 2801 | } |
2802 | ||
89db421e | 2803 | int user_change_status(LDAP *ldap_handle, char *dn_path, |
2804 | char *user_name, char *MoiraId, | |
2805 | int operation) | |
cd9e6b16 | 2806 | { |
89db421e | 2807 | char filter[128]; |
cd9e6b16 | 2808 | char *attr_array[3]; |
2809 | char temp[256]; | |
2810 | char distinguished_name[1024]; | |
cd9e6b16 | 2811 | char **modvalues; |
89db421e | 2812 | char *mitMoiraId_v[] = {NULL, NULL}; |
cd9e6b16 | 2813 | LDAPMod *mods[20]; |
2814 | LK_ENTRY *group_base; | |
2815 | int group_count; | |
2816 | int rc; | |
2817 | int i; | |
2818 | int n; | |
2819 | ULONG ulongValue; | |
2820 | ||
f75f605a | 2821 | if (!check_string(user_name)) |
78af4e6e | 2822 | { |
f75f605a | 2823 | com_err(whoami, 0, "invalid LDAP user name %s", user_name); |
89db421e | 2824 | return(AD_INVALID_NAME); |
78af4e6e | 2825 | } |
f75f605a | 2826 | |
cd9e6b16 | 2827 | group_count = 0; |
2828 | group_base = NULL; | |
89db421e | 2829 | |
2830 | if (strlen(MoiraId) != 0) | |
cd9e6b16 | 2831 | { |
c0bd7667 | 2832 | sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId); |
89db421e | 2833 | attr_array[0] = "UserAccountControl"; |
2834 | attr_array[1] = NULL; | |
2835 | if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array, | |
2836 | &group_base, &group_count)) != 0) | |
2837 | { | |
2838 | com_err(whoami, 0, "LDAP server couldn't process user %s : %s", | |
2839 | user_name, ldap_err2string(rc)); | |
2840 | return(rc); | |
2841 | } | |
2842 | } | |
c0bd7667 | 2843 | if (group_count != 1) |
89db421e | 2844 | { |
c0bd7667 | 2845 | linklist_free(group_base); |
2846 | group_count = 0; | |
2847 | group_base = NULL; | |
89db421e | 2848 | sprintf(filter, "(sAMAccountName=%s)", user_name); |
2849 | attr_array[0] = "UserAccountControl"; | |
2850 | attr_array[1] = NULL; | |
2851 | if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array, | |
2852 | &group_base, &group_count)) != 0) | |
2853 | { | |
2854 | com_err(whoami, 0, "LDAP server couldn't process user %s : %s", | |
2855 | user_name, ldap_err2string(rc)); | |
2856 | return(rc); | |
2857 | } | |
cd9e6b16 | 2858 | } |
2859 | ||
78af4e6e | 2860 | if (group_count != 1) |
cd9e6b16 | 2861 | { |
f75f605a | 2862 | linklist_free(group_base); |
2863 | com_err(whoami, 0, "LDAP server unable to find user %s in AD", | |
2864 | user_name); | |
2865 | return(LDAP_NO_SUCH_OBJECT); | |
cd9e6b16 | 2866 | } |
2867 | ||
2868 | strcpy(distinguished_name, group_base->dn); | |
2869 | ulongValue = atoi((*group_base).value); | |
2870 | if (operation == MEMBER_DEACTIVATE) | |
2871 | ulongValue |= UF_ACCOUNTDISABLE; | |
2872 | else | |
2873 | ulongValue &= ~UF_ACCOUNTDISABLE; | |
2874 | sprintf(temp, "%ld", ulongValue); | |
2875 | if ((rc = construct_newvalues(group_base, group_count, (*group_base).value, | |
2876 | temp, &modvalues, REPLACE)) == 1) | |
f75f605a | 2877 | goto cleanup; |
cd9e6b16 | 2878 | linklist_free(group_base); |
2879 | group_base = NULL; | |
2880 | group_count = 0; | |
2881 | n = 0; | |
2882 | ADD_ATTR("UserAccountControl", modvalues, LDAP_MOD_REPLACE); | |
89db421e | 2883 | if (strlen(MoiraId) != 0) |
2884 | { | |
2885 | mitMoiraId_v[0] = MoiraId; | |
2886 | ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_REPLACE); | |
2887 | } | |
cd9e6b16 | 2888 | mods[n] = NULL; |
f75f605a | 2889 | rc = ldap_modify_s(ldap_handle, distinguished_name, mods); |
cd9e6b16 | 2890 | for (i = 0; i < n; i++) |
2891 | free(mods[i]); | |
2892 | free_values(modvalues); | |
2893 | if (rc != LDAP_SUCCESS) | |
2894 | { | |
f75f605a | 2895 | com_err(whoami, 0, "LDAP server could not change status of user %s : %s", |
2896 | user_name, ldap_err2string(rc)); | |
cd9e6b16 | 2897 | } |
2898 | cleanup: | |
f75f605a | 2899 | return(rc); |
cd9e6b16 | 2900 | } |
2901 | ||
89db421e | 2902 | int user_delete(LDAP *ldap_handle, char *dn_path, |
2903 | char *u_name, char *MoiraId) | |
cd9e6b16 | 2904 | { |
89db421e | 2905 | char filter[128]; |
cd9e6b16 | 2906 | char *attr_array[3]; |
2907 | char distinguished_name[1024]; | |
2908 | char user_name[512]; | |
2909 | LK_ENTRY *group_base; | |
2910 | int group_count; | |
2911 | int rc; | |
2912 | ||
2913 | if (!check_string(u_name)) | |
89db421e | 2914 | return(AD_INVALID_NAME); |
2915 | ||
cd9e6b16 | 2916 | strcpy(user_name, u_name); |
2917 | group_count = 0; | |
2918 | group_base = NULL; | |
89db421e | 2919 | |
2920 | if (strlen(MoiraId) != 0) | |
cd9e6b16 | 2921 | { |
c0bd7667 | 2922 | sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId); |
89db421e | 2923 | attr_array[0] = "name"; |
2924 | attr_array[1] = NULL; | |
2925 | if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array, | |
2926 | &group_base, &group_count)) != 0) | |
2927 | { | |
2928 | com_err(whoami, 0, "LDAP server couldn't process user %s : %s", | |
2929 | user_name, ldap_err2string(rc)); | |
2930 | goto cleanup; | |
2931 | } | |
2932 | } | |
c0bd7667 | 2933 | if (group_count != 1) |
89db421e | 2934 | { |
c0bd7667 | 2935 | linklist_free(group_base); |
2936 | group_count = 0; | |
2937 | group_base = NULL; | |
89db421e | 2938 | sprintf(filter, "(sAMAccountName=%s)", user_name); |
2939 | attr_array[0] = "name"; | |
2940 | attr_array[1] = NULL; | |
2941 | if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array, | |
2942 | &group_base, &group_count)) != 0) | |
2943 | { | |
2944 | com_err(whoami, 0, "LDAP server couldn't process user %s : %s", | |
2945 | user_name, ldap_err2string(rc)); | |
2946 | goto cleanup; | |
2947 | } | |
cd9e6b16 | 2948 | } |
2949 | ||
78af4e6e | 2950 | if (group_count != 1) |
cd9e6b16 | 2951 | { |
f75f605a | 2952 | com_err(whoami, 0, "LDAP server unable to find user %s in AD", |
2953 | user_name); | |
cd9e6b16 | 2954 | goto cleanup; |
2955 | } | |
2956 | ||
2957 | strcpy(distinguished_name, group_base->dn); | |
2958 | if (rc = ldap_delete_s(ldap_handle, distinguished_name)) | |
2959 | { | |
f75f605a | 2960 | com_err(whoami, 0, "LDAP server couldn't process user %s : %s", |
2961 | user_name, ldap_err2string(rc)); | |
cd9e6b16 | 2962 | } |
2963 | ||
2964 | cleanup: | |
2965 | linklist_free(group_base); | |
78af4e6e | 2966 | return(0); |
cd9e6b16 | 2967 | } |
2968 | ||
2969 | void linklist_free(LK_ENTRY *linklist_base) | |
2970 | { | |
2971 | LK_ENTRY *linklist_previous; | |
2972 | ||
2973 | while (linklist_base != NULL) | |
2974 | { | |
2975 | if (linklist_base->dn != NULL) | |
2976 | free(linklist_base->dn); | |
2977 | if (linklist_base->attribute != NULL) | |
2978 | free(linklist_base->attribute); | |
2979 | if (linklist_base->value != NULL) | |
2980 | free(linklist_base->value); | |
2981 | if (linklist_base->member != NULL) | |
2982 | free(linklist_base->member); | |
2983 | if (linklist_base->type != NULL) | |
2984 | free(linklist_base->type); | |
2985 | if (linklist_base->list != NULL) | |
2986 | free(linklist_base->list); | |
2987 | linklist_previous = linklist_base; | |
2988 | linklist_base = linklist_previous->next; | |
2989 | free(linklist_previous); | |
2990 | } | |
2991 | } | |
2992 | ||
2993 | void free_values(char **modvalues) | |
2994 | { | |
2995 | int i; | |
2996 | ||
2997 | i = 0; | |
2998 | if (modvalues != NULL) | |
2999 | { | |
3000 | while (modvalues[i] != NULL) | |
3001 | { | |
3002 | free(modvalues[i]); | |
3003 | modvalues[i] = NULL; | |
3004 | ++i; | |
3005 | } | |
3006 | free(modvalues); | |
3007 | } | |
3008 | } | |
3009 | ||
3010 | int sid_update(LDAP *ldap_handle, char *dn_path) | |
3011 | { | |
3012 | LK_ENTRY *ptr; | |
3013 | int rc; | |
3014 | unsigned char temp[126]; | |
3015 | char *av[3]; | |
3016 | ||
3017 | ptr = sid_base; | |
3018 | ||
3019 | while (ptr != NULL) | |
3020 | { | |
3021 | memset(temp, 0, sizeof(temp)); | |
3022 | convert_b_to_a(temp, ptr->value, ptr->length); | |
5b8457c5 | 3023 | if (!ptr->member) |
3024 | continue; | |
cd9e6b16 | 3025 | av[0] = ptr->member; |
3026 | av[1] = temp; | |
3027 | if (ptr->type == (char *)GROUPS) | |
3028 | { | |
3029 | ptr->type = NULL; | |
3030 | rc = mr_query("add_list_sid_by_name", 2, av, NULL, NULL); | |
3031 | } | |
3032 | else if (ptr->type == (char *)USERS) | |
3033 | { | |
3034 | ptr->type = NULL; | |
3035 | rc = mr_query("add_user_sid_by_login", 2, av, NULL, NULL); | |
3036 | } | |
3037 | ptr = ptr->next; | |
3038 | } | |
3039 | return(0); | |
3040 | } | |
3041 | ||
3042 | void convert_b_to_a(char *string, UCHAR *binary, int length) | |
3043 | { | |
3044 | int i; | |
3045 | int j; | |
3046 | UCHAR tmp; | |
3047 | ||
3048 | j = 0; | |
3049 | for (i = 0; i < length; i++) | |
3050 | { | |
3051 | tmp = binary[i]; | |
3052 | string[j] = tmp; | |
3053 | string[j] >>= 4; | |
3054 | string[j] &= 0x0f; | |
3055 | string[j] += 0x30; | |
3056 | if (string[j] > '9') | |
3057 | string[j] += 0x27; | |
3058 | ++j; | |
3059 | string[j] = tmp & 0x0f; | |
3060 | string[j] += 0x30; | |
3061 | if (string[j] > '9') | |
3062 | string[j] += 0x27; | |
3063 | j++; | |
3064 | } | |
3065 | string[j] = 0; | |
3066 | } | |
3067 | ||
3068 | static int illegalchars[] = { | |
3069 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^@ - ^O */ | |
3070 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^P - ^_ */ | |
3071 | 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, /* SPACE - / */ | |
3072 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, /* 0 - ? */ | |
f75f605a | 3073 | 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* @ - O */ |
cd9e6b16 | 3074 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, /* P - _ */ |
3075 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ` - o */ | |
3076 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, /* p - ^? */ | |
3077 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
3078 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
3079 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
3080 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
3081 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
3082 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
3083 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
3084 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
3085 | }; | |
3086 | ||
3087 | int check_string(char *s) | |
3088 | { | |
78af4e6e | 3089 | char character; |
3090 | ||
cd9e6b16 | 3091 | for (; *s; s++) |
3092 | { | |
78af4e6e | 3093 | character = *s; |
3094 | if (isupper(character)) | |
3095 | character = tolower(character); | |
3096 | if (illegalchars[(unsigned) character]) | |
cd9e6b16 | 3097 | return 0; |
3098 | } | |
3099 | return 1; | |
3100 | } | |
3101 | ||
3102 | int mr_connect_cl(char *server, char *client, int version, int auth) | |
3103 | { | |
984c91b7 | 3104 | int status; |
3105 | char *motd; | |
3106 | char temp[128]; | |
cd9e6b16 | 3107 | |
3108 | status = mr_connect(server); | |
3109 | if (status) | |
3110 | { | |
3111 | com_err(whoami, status, "while connecting to Moira"); | |
aea5154c | 3112 | return status; |
cd9e6b16 | 3113 | } |
3114 | ||
3115 | status = mr_motd(&motd); | |
3116 | if (status) | |
3117 | { | |
3118 | mr_disconnect(); | |
3119 | com_err(whoami, status, "while checking server status"); | |
aea5154c | 3120 | return status; |
cd9e6b16 | 3121 | } |
3122 | if (motd) | |
3123 | { | |
984c91b7 | 3124 | sprintf(temp, "The Moira server is currently unavailable: %s", motd); |
3125 | com_err(whoami, status, temp); | |
cd9e6b16 | 3126 | mr_disconnect(); |
aea5154c | 3127 | return status; |
cd9e6b16 | 3128 | } |
3129 | ||
3130 | status = mr_version(version); | |
3131 | if (status) | |
3132 | { | |
3133 | if (status == MR_UNKNOWN_PROC) | |
f78c7eaf | 3134 | { |
3135 | if (version > 2) | |
3136 | status = MR_VERSION_HIGH; | |
3137 | else | |
3138 | status = MR_SUCCESS; | |
3139 | } | |
cd9e6b16 | 3140 | |
3141 | if (status == MR_VERSION_HIGH) | |
f78c7eaf | 3142 | { |
3143 | com_err(whoami, 0, "Warning: This client is running newer code than the server."); | |
3144 | com_err(whoami, 0, "Some operations may not work."); | |
3145 | } | |
cd9e6b16 | 3146 | else if (status && status != MR_VERSION_LOW) |
f78c7eaf | 3147 | { |
3148 | com_err(whoami, status, "while setting query version number."); | |
3149 | mr_disconnect(); | |
aea5154c | 3150 | return status; |
f78c7eaf | 3151 | } |
cd9e6b16 | 3152 | } |
3153 | ||
3154 | if (auth) | |
3155 | { | |
3156 | status = mr_auth(client); | |
3157 | if (status) | |
f78c7eaf | 3158 | { |
3159 | com_err(whoami, status, "while authenticating to Moira."); | |
3160 | mr_disconnect(); | |
aea5154c | 3161 | return status; |
f78c7eaf | 3162 | } |
cd9e6b16 | 3163 | } |
3164 | ||
aea5154c | 3165 | return MR_SUCCESS; |
cd9e6b16 | 3166 | } |
3167 | ||
f78c7eaf | 3168 | void AfsToWinAfs(char* path, char* winPath) |
3169 | { | |
3170 | char* pathPtr; | |
3171 | char* winPathPtr; | |
3172 | strcpy(winPath, WINAFS); | |
3173 | pathPtr = path + strlen(AFS); | |
3174 | winPathPtr = winPath + strlen(WINAFS); | |
3175 | ||
3176 | while (*pathPtr) | |
3177 | { | |
3178 | if (*pathPtr == '/') | |
3179 | *winPathPtr = '\\'; | |
3180 | else | |
3181 | *winPathPtr = *pathPtr; | |
3182 | ||
3183 | pathPtr++; | |
3184 | winPathPtr++; | |
3185 | } | |
3186 | } | |
89db421e | 3187 | |
3188 | int make_new_group(LDAP *ldap_handle, char *dn_path, char *MoiraId, | |
3189 | char *group_name, char *group_ou, char *group_membership, | |
3190 | int group_security_flag, int updateGroup) | |
3191 | { | |
3192 | char *av[3]; | |
3193 | char *call_args[7]; | |
3194 | int rc; | |
3195 | ||
3196 | av[0] = group_name; | |
3197 | call_args[0] = (char *)ldap_handle; | |
3198 | call_args[1] = dn_path; | |
3199 | call_args[2] = group_name; | |
3200 | call_args[3] = (char *)(MOIRA_USERS | MOIRA_KERBEROS | MOIRA_STRINGS); | |
3201 | call_args[4] = (char *)updateGroup; | |
3202 | call_args[5] = MoiraId; | |
3203 | call_args[6] = NULL; | |
3204 | sid_base = NULL; | |
3205 | sid_ptr = &sid_base; | |
3206 | callback_rc = 0; | |
3207 | if (rc = mr_query("get_list_info", 1, av, group_create, call_args)) | |
3208 | { | |
3209 | moira_disconnect(); | |
3210 | com_err(whoami, 0, "Couldn't create list %s : %s", group_name, error_message(rc)); | |
3211 | return(rc); | |
3212 | } | |
3213 | if (callback_rc) | |
3214 | { | |
3215 | moira_disconnect(); | |
3216 | com_err(whoami, 0, "Couldn't create list %s", group_name); | |
3217 | return(callback_rc); | |
3218 | } | |
3219 | ||
3220 | if (sid_base != NULL) | |
3221 | { | |
3222 | sid_update(ldap_handle, dn_path); | |
3223 | linklist_free(sid_base); | |
3224 | sid_base = NULL; | |
3225 | } | |
3226 | return(0); | |
3227 | } | |
3228 | ||
3229 | int populate_group(LDAP *ldap_handle, char *dn_path, char *group_name, | |
3230 | char *group_ou, char *group_membership, | |
3231 | int group_security_flag, char *MoiraId) | |
3232 | { | |
3233 | char *av[3]; | |
3234 | char *call_args[7]; | |
3235 | char *pUserOu; | |
3236 | LK_ENTRY *ptr; | |
3237 | int rc; | |
3238 | ||
3239 | com_err(whoami, 0, "Populating group %s", group_name); | |
3240 | av[0] = group_name; | |
3241 | call_args[0] = (char *)ldap_handle; | |
3242 | call_args[1] = dn_path; | |
3243 | call_args[2] = group_name; | |
3244 | call_args[3] = (char *)(MOIRA_USERS | MOIRA_KERBEROS | MOIRA_STRINGS); | |
3245 | call_args[4] = NULL; | |
3246 | member_base = NULL; | |
3247 | if (rc = mr_query("get_end_members_of_list", 1, av, | |
3248 | member_list_build, call_args)) | |
3249 | { | |
3250 | com_err(whoami, 0, "Couldn't populate list %s : %s", | |
3251 | group_name, error_message(rc)); | |
3252 | return(3); | |
3253 | } | |
3254 | if (member_base != NULL) | |
3255 | { | |
3256 | ptr = member_base; | |
3257 | while (ptr != NULL) | |
3258 | { | |
3259 | if (!strcasecmp(ptr->type, "LIST")) | |
3260 | { | |
3261 | ptr = ptr->next; | |
3262 | continue; | |
3263 | } | |
3264 | pUserOu = user_ou; | |
3265 | if (!strcasecmp(ptr->type, "STRING")) | |
3266 | { | |
3267 | if (contact_create(ldap_handle, dn_path, ptr->member, contact_ou)) | |
3268 | return(3); | |
3269 | pUserOu = contact_ou; | |
3270 | } | |
3271 | else if (!strcasecmp(ptr->type, "KERBEROS")) | |
3272 | { | |
3273 | if (contact_create(ldap_handle, dn_path, ptr->member, kerberos_ou)) | |
3274 | return(3); | |
3275 | pUserOu = kerberos_ou; | |
3276 | } | |
3277 | rc = member_add(ldap_handle, dn_path, group_name, | |
3278 | group_ou, group_membership, ptr->member, | |
3279 | pUserOu, MoiraId); | |
3280 | ptr = ptr->next; | |
3281 | } | |
3282 | linklist_free(member_base); | |
3283 | member_base = NULL; | |
3284 | } | |
3285 | return(0); | |
3286 | } | |
3287 | ||
3288 | int process_group(LDAP *ldap_handle, char *dn_path, char *MoiraId, | |
3289 | char *group_name, char *group_ou, char *group_membership, | |
3290 | int group_security_flag, int type) | |
3291 | { | |
3292 | char before_desc[512]; | |
3293 | char before_name[256]; | |
3294 | char before_group_ou[256]; | |
3295 | char before_group_membership[2]; | |
3296 | char distinguishedName[256]; | |
3297 | char ad_distinguishedName[256]; | |
3298 | char filter[128]; | |
3299 | char *attr_array[3]; | |
3300 | int before_security_flag; | |
3301 | int group_count; | |
3302 | int rc; | |
3303 | LK_ENTRY *group_base; | |
3304 | LK_ENTRY *ptr; | |
3305 | char ou_both[512]; | |
3306 | char ou_security[512]; | |
3307 | char ou_distribution[512]; | |
3308 | char ou_neither[512]; | |
3309 | ||
3310 | memset(ad_distinguishedName, '\0', sizeof(ad_distinguishedName)); | |
3311 | sprintf(distinguishedName, "CN=%s,%s,%s", group_name, group_ou, dn_path); | |
3312 | ||
3313 | ||
3314 | memset(filter, '\0', sizeof(filter)); | |
3315 | group_base = NULL; | |
3316 | group_count = 0; | |
3317 | if (rc = ad_get_group(ldap_handle, dn_path, group_name, | |
3318 | "*", MoiraId, | |
3319 | "distinguishedName", &group_base, | |
3320 | &group_count, filter)) | |
3321 | return(rc); | |
3322 | ||
3323 | if (type == CHECK_GROUPS) | |
3324 | { | |
3325 | if (group_count == 1) | |
3326 | { | |
3327 | if (!strcasecmp(group_base->value, distinguishedName)) | |
3328 | { | |
3329 | linklist_free(group_base); | |
3330 | return(0); | |
3331 | } | |
3332 | } | |
3333 | linklist_free(group_base); | |
3334 | if (group_count == 0) | |
3335 | return(AD_NO_GROUPS_FOUND); | |
3336 | if (group_count == 1) | |
3337 | return(AD_WRONG_GROUP_DN_FOUND); | |
3338 | return(AD_MULTIPLE_GROUPS_FOUND); | |
3339 | } | |
3340 | if (group_count == 0) | |
3341 | { | |
3342 | return(AD_NO_GROUPS_FOUND); | |
3343 | } | |
3344 | if (group_count > 1) | |
3345 | { | |
3346 | ptr = group_base; | |
3347 | while (ptr != NULL) | |
3348 | { | |
3349 | if (!strcasecmp(distinguishedName, ptr->value)) | |
3350 | break; | |
3351 | ptr = ptr->next; | |
3352 | } | |
3353 | if (ptr == NULL) | |
3354 | { | |
3355 | com_err(whoami, 0, "%d groups with moira id = %s", group_count, MoiraId); | |
3356 | ptr = group_base; | |
3357 | while (ptr != NULL) | |
3358 | { | |
3359 | com_err(whoami, 0, "%s with moira id = %s", ptr->value, MoiraId); | |
3360 | ptr = ptr->next; | |
3361 | } | |
3362 | linklist_free(group_base); | |
3363 | return(AD_MULTIPLE_GROUPS_FOUND); | |
6c8f12af | 3364 | } |
89db421e | 3365 | ptr = group_base; |
3366 | while (ptr != NULL) | |
3367 | { | |
3368 | if (strcasecmp(distinguishedName, ptr->value)) | |
3369 | rc = ldap_delete_s(ldap_handle, ptr->value); | |
3370 | ptr = ptr->next; | |
3371 | } | |
3372 | linklist_free(group_base); | |
3373 | memset(filter, '\0', sizeof(filter)); | |
3374 | group_base = NULL; | |
3375 | group_count = 0; | |
3376 | if (rc = ad_get_group(ldap_handle, dn_path, group_name, | |
3377 | "*", MoiraId, | |
3378 | "distinguishedName", &group_base, | |
3379 | &group_count, filter)) | |
3380 | return(rc); | |
3381 | if (group_count == 0) | |
3382 | return(AD_NO_GROUPS_FOUND); | |
3383 | if (group_count > 1) | |
3384 | return(AD_MULTIPLE_GROUPS_FOUND); | |
3385 | } | |
3386 | ||
3387 | strcpy(ad_distinguishedName, group_base->value); | |
3388 | linklist_free(group_base); | |
3389 | group_base = NULL; | |
3390 | group_count = 0; | |
3391 | ||
3392 | attr_array[0] = "sAMAccountName"; | |
3393 | attr_array[1] = NULL; | |
3394 | if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array, | |
3395 | &group_base, &group_count)) != 0) | |
3396 | { | |
3397 | com_err(whoami, 0, "LDAP server unable to get list info with MoiraId = %s: %s", | |
3398 | MoiraId, ldap_err2string(rc)); | |
3399 | return(rc); | |
3400 | } | |
3401 | sprintf(filter, "(sAMAccountName=%s)", group_base->value); | |
3402 | ||
3403 | if (!strcasecmp(ad_distinguishedName, distinguishedName)) | |
3404 | { | |
3405 | linklist_free(group_base); | |
3406 | group_base = NULL; | |
3407 | group_count = 0; | |
3408 | return(0); | |
3409 | } | |
3410 | linklist_free(group_base); | |
3411 | group_base = NULL; | |
3412 | group_count = 0; | |
3413 | memset(ou_both, '\0', sizeof(ou_both)); | |
3414 | memset(ou_security, '\0', sizeof(ou_security)); | |
3415 | memset(ou_distribution, '\0', sizeof(ou_distribution)); | |
3416 | memset(ou_neither, '\0', sizeof(ou_neither)); | |
3417 | memset(before_name, '\0', sizeof(before_name)); | |
3418 | memset(before_desc, '\0', sizeof(before_desc)); | |
3419 | memset(before_group_membership, '\0', sizeof(before_group_membership)); | |
3420 | attr_array[0] = "name"; | |
3421 | attr_array[1] = NULL; | |
3422 | if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array, | |
3423 | &group_base, &group_count)) != 0) | |
3424 | { | |
3425 | com_err(whoami, 0, "LDAP server unable to get list name with MoiraId = %s: %s", | |
3426 | MoiraId, ldap_err2string(rc)); | |
3427 | return(rc); | |
3428 | } | |
3429 | strcpy(before_name, group_base->value); | |
3430 | linklist_free(group_base); | |
3431 | group_base = NULL; | |
3432 | group_count = 0; | |
3433 | attr_array[0] = "description"; | |
3434 | attr_array[1] = NULL; | |
3435 | if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array, | |
3436 | &group_base, &group_count)) != 0) | |
3437 | { | |
3438 | com_err(whoami, 0, | |
3439 | "LDAP server unable to get list description with MoiraId = %s: %s", | |
3440 | MoiraId, ldap_err2string(rc)); | |
3441 | return(rc); | |
3442 | } | |
c0bd7667 | 3443 | if (group_count != 0) |
3444 | { | |
3445 | strcpy(before_desc, group_base->value); | |
3446 | linklist_free(group_base); | |
3447 | group_base = NULL; | |
3448 | group_count = 0; | |
3449 | } | |
89db421e | 3450 | change_to_lower_case(ad_distinguishedName); |
3451 | strcpy(ou_both, group_ou_both); | |
3452 | change_to_lower_case(ou_both); | |
3453 | strcpy(ou_security, group_ou_security); | |
3454 | change_to_lower_case(ou_security); | |
3455 | strcpy(ou_distribution, group_ou_distribution); | |
3456 | change_to_lower_case(ou_distribution); | |
3457 | strcpy(ou_neither, group_ou_neither); | |
3458 | change_to_lower_case(ou_neither); | |
3459 | if (strstr(ad_distinguishedName, ou_both)) | |
3460 | { | |
3461 | strcpy(before_group_ou, group_ou_both); | |
3462 | before_group_membership[0] = 'B'; | |
3463 | before_security_flag = 1; | |
3464 | } | |
3465 | else if (strstr(ad_distinguishedName, ou_security)) | |
3466 | { | |
3467 | strcpy(before_group_ou, group_ou_security); | |
3468 | before_group_membership[0] = 'S'; | |
3469 | before_security_flag = 1; | |
3470 | } | |
3471 | else if (strstr(ad_distinguishedName, ou_distribution)) | |
3472 | { | |
3473 | strcpy(before_group_ou, group_ou_distribution); | |
3474 | before_group_membership[0] = 'D'; | |
3475 | before_security_flag = 0; | |
3476 | } | |
3477 | else if (strstr(ad_distinguishedName, ou_neither)) | |
3478 | { | |
3479 | strcpy(before_group_ou, group_ou_neither); | |
3480 | before_group_membership[0] = 'N'; | |
3481 | before_security_flag = 0; | |
3482 | } | |
3483 | else | |
3484 | return(AD_NO_OU_FOUND); | |
3485 | rc = group_rename(ldap_handle, dn_path, before_name, before_group_membership, | |
3486 | before_group_ou, before_security_flag, before_desc, | |
3487 | group_name, group_membership, group_ou, group_security_flag, | |
3488 | before_desc, MoiraId, filter); | |
3489 | return(rc); | |
3490 | } | |
3491 | ||
3492 | void change_to_lower_case(char *ptr) | |
3493 | { | |
3494 | int i; | |
3495 | ||
3496 | for (i = 0; i < (int)strlen(ptr); i++) | |
3497 | { | |
3498 | ptr[i] = tolower(ptr[i]); | |
3499 | } | |
3500 | } | |
3501 | ||
3502 | int ad_get_group(LDAP *ldap_handle, char *dn_path, | |
3503 | char *group_name, char *group_membership, | |
3504 | char *MoiraId, char *attribute, | |
3505 | LK_ENTRY **linklist_base, int *linklist_count, | |
3506 | char *rFilter) | |
3507 | { | |
3e586ecf | 3508 | LK_ENTRY *pPtr; |
c0bd7667 | 3509 | char filter[128]; |
3510 | char *attr_array[3]; | |
89db421e | 3511 | int rc; |
3512 | ||
3513 | (*linklist_base) = NULL; | |
3514 | (*linklist_count) = 0; | |
3515 | if (strlen(rFilter) != 0) | |
3516 | { | |
3517 | strcpy(filter, rFilter); | |
3518 | attr_array[0] = attribute; | |
3519 | attr_array[1] = NULL; | |
3520 | if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array, | |
3521 | linklist_base, linklist_count)) != 0) | |
3522 | { | |
3523 | com_err(whoami, 0, "LDAP server unable to get list info with MoiraId = %s: %s", | |
3524 | MoiraId, ldap_err2string(rc)); | |
3525 | return(rc); | |
3526 | } | |
3527 | if ((*linklist_count) == 1) | |
3528 | { | |
3529 | strcpy(rFilter, filter); | |
3530 | return(0); | |
3531 | } | |
3532 | } | |
3533 | ||
3534 | linklist_free((*linklist_base)); | |
3535 | (*linklist_base) = NULL; | |
3536 | (*linklist_count) = 0; | |
3537 | if (strlen(MoiraId) != 0) | |
3538 | { | |
c0bd7667 | 3539 | sprintf(filter, "(&(objectClass=group)(mitMoiraId=%s))", MoiraId); |
89db421e | 3540 | attr_array[0] = attribute; |
3541 | attr_array[1] = NULL; | |
3542 | if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array, | |
3543 | linklist_base, linklist_count)) != 0) | |
3544 | { | |
3545 | com_err(whoami, 0, "LDAP server unable to get list info with MoiraId = %s: %s", | |
3546 | MoiraId, ldap_err2string(rc)); | |
3547 | return(rc); | |
3548 | } | |
3549 | } | |
3e586ecf | 3550 | if ((*linklist_count) > 1) |
3551 | { | |
3552 | com_err(whoami, 0, "multiple groups with mitMoiraId = %s", MoiraId); | |
3553 | pPtr = (*linklist_base); | |
3554 | while (pPtr) | |
3555 | { | |
3556 | com_err(whoami, 0, "groups %s has mitMoiraId = %s", pPtr->value, MoiraId); | |
3557 | pPtr = pPtr->next; | |
3558 | } | |
3559 | linklist_free((*linklist_base)); | |
3560 | (*linklist_base) = NULL; | |
3561 | (*linklist_count) = 0; | |
3562 | } | |
89db421e | 3563 | if ((*linklist_count) == 1) |
3564 | { | |
3565 | strcpy(rFilter, filter); | |
3566 | return(0); | |
3567 | } | |
3568 | ||
3569 | linklist_free((*linklist_base)); | |
3570 | (*linklist_base) = NULL; | |
3571 | (*linklist_count) = 0; | |
3572 | sprintf(filter, "(sAMAccountName=%s_group)", group_name); | |
3573 | attr_array[0] = attribute; | |
3574 | attr_array[1] = NULL; | |
3575 | if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array, | |
3576 | linklist_base, linklist_count)) != 0) | |
3577 | { | |
3578 | com_err(whoami, 0, "LDAP server unable to get list info with MoiraId = %s: %s", | |
3579 | MoiraId, ldap_err2string(rc)); | |
3580 | return(rc); | |
3581 | } | |
3582 | if ((*linklist_count) == 1) | |
3583 | { | |
3584 | strcpy(rFilter, filter); | |
3585 | return(0); | |
3586 | } | |
3587 | ||
89db421e | 3588 | return(0); |
3589 | } | |
3590 | ||
3591 | int check_user(LDAP *ldap_handle, char *dn_path, char *UserName, char *MoiraId) | |
3592 | { | |
3593 | char filter[128]; | |
3594 | char *attr_array[3]; | |
3595 | char SamAccountName[64]; | |
3596 | int group_count; | |
3597 | int rc; | |
3598 | LK_ENTRY *group_base; | |
c0bd7667 | 3599 | LK_ENTRY *gPtr; |
89db421e | 3600 | |
3601 | group_count = 0; | |
3602 | group_base = NULL; | |
3603 | ||
3604 | if (strlen(MoiraId) != 0) | |
3605 | { | |
c0bd7667 | 3606 | sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId); |
89db421e | 3607 | attr_array[0] = "sAMAccountName"; |
3608 | attr_array[1] = NULL; | |
3609 | if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array, | |
3610 | &group_base, &group_count)) != 0) | |
3611 | { | |
3612 | com_err(whoami, 0, "LDAP server couldn't process user %s : %s", | |
3613 | UserName, ldap_err2string(rc)); | |
3614 | return(rc); | |
3615 | } | |
c0bd7667 | 3616 | if (group_count > 1) |
3617 | { | |
3618 | com_err(whoami, 0, "multiple users exist with MoiraId = %s", | |
3619 | MoiraId); | |
3620 | gPtr = group_base; | |
3621 | while (gPtr) | |
3622 | { | |
3623 | com_err(whoami, 0, "user %s exist with MoiraId = %s", | |
3624 | gPtr->value, MoiraId); | |
3625 | gPtr = gPtr->next; | |
3626 | } | |
3627 | } | |
89db421e | 3628 | } |
c0bd7667 | 3629 | if (group_count != 1) |
89db421e | 3630 | { |
c0bd7667 | 3631 | linklist_free(group_base); |
3632 | group_count = 0; | |
3633 | group_base = NULL; | |
89db421e | 3634 | sprintf(filter, "(sAMAccountName=%s)", UserName); |
3635 | attr_array[0] = "sAMAccountName"; | |
3636 | attr_array[1] = NULL; | |
3637 | if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array, | |
3638 | &group_base, &group_count)) != 0) | |
3639 | { | |
3640 | com_err(whoami, 0, "LDAP server couldn't process user %s : %s", | |
3641 | UserName, ldap_err2string(rc)); | |
3642 | return(rc); | |
3643 | } | |
3644 | } | |
3645 | ||
3646 | if (group_count != 1) | |
3647 | { | |
3648 | linklist_free(group_base); | |
3649 | return(AD_NO_USER_FOUND); | |
3650 | } | |
3651 | strcpy(SamAccountName, group_base->value); | |
3652 | linklist_free(group_base); | |
3653 | group_count = 0; | |
3654 | rc = 0; | |
3655 | if (strcmp(SamAccountName, UserName)) | |
3656 | { | |
3657 | rc = user_rename(ldap_handle, dn_path, SamAccountName, | |
3658 | UserName); | |
3659 | } | |
3660 | return(0); | |
3661 | } | |
6c8f12af | 3662 | |
3663 | void container_get_dn(char *src, char *dest) | |
3664 | { | |
3665 | char *sPtr; | |
3666 | char *array[20]; | |
3667 | char name[256]; | |
3668 | int n; | |
3669 | ||
3670 | memset(array, '\0', 20 * sizeof(array[0])); | |
3671 | ||
3672 | if (strlen(src) == 0) | |
3673 | return; | |
3674 | strcpy(name, src); | |
3675 | sPtr = name; | |
3676 | n = 0; | |
3677 | array[n] = name; | |
3678 | ++n; | |
3679 | while (*sPtr) | |
3680 | { | |
3681 | if ((*sPtr) == '/') | |
3682 | { | |
3683 | (*sPtr) = '\0'; | |
3684 | ++sPtr; | |
3685 | array[n] = sPtr; | |
3686 | ++n; | |
3687 | } | |
3688 | else | |
3689 | ++sPtr; | |
3690 | } | |
3691 | strcpy(dest, "OU="); | |
3692 | while (n != 0) | |
3693 | { | |
3694 | strcat(dest, array[n-1]); | |
3695 | --n; | |
3696 | if (n > 0) | |
3697 | { | |
3698 | strcat(dest, ",OU="); | |
3699 | } | |
3700 | } | |
3701 | return; | |
3702 | } | |
3703 | ||
3704 | void container_get_name(char *src, char *dest) | |
3705 | { | |
3706 | char *sPtr; | |
3707 | char *dPtr; | |
3708 | ||
3709 | if (strlen(src) == 0) | |
3710 | return; | |
3711 | sPtr = src; | |
3712 | dPtr = src; | |
3713 | while (*sPtr) | |
3714 | { | |
3715 | if ((*sPtr) == '/') | |
3716 | { | |
3717 | dPtr = sPtr; | |
3718 | ++dPtr; | |
3719 | } | |
3720 | ++sPtr; | |
3721 | } | |
3722 | strcpy(dest, dPtr); | |
3723 | return; | |
3724 | } | |
3725 | ||
3726 | void container_check(LDAP *ldap_handle, char *dn_path, char *name) | |
3727 | { | |
3728 | char cName[256]; | |
3729 | char *av[7]; | |
3730 | int i; | |
3731 | int rc; | |
3732 | ||
3733 | strcpy(cName, name); | |
3734 | for (i = 0; i < (int)strlen(cName); i++) | |
3735 | { | |
3736 | if (cName[i] == '/') | |
3737 | { | |
3738 | cName[i] = '\0'; | |
3739 | av[CONTAINER_NAME] = cName; | |
3740 | av[CONTAINER_DESC] = ""; | |
3741 | av[CONTAINER_LOCATION] = ""; | |
3742 | av[CONTAINER_CONTACT] = ""; | |
3743 | av[CONTAINER_TYPE] = ""; | |
3744 | av[CONTAINER_ID] = ""; | |
3745 | av[CONTAINER_ROWID] = ""; | |
3746 | rc = container_create(ldap_handle, dn_path, 7, av); | |
3747 | if (rc == LDAP_SUCCESS) | |
3748 | { | |
3749 | com_err(whoami, 0, "container %s created without a mitMoiraId", cName); | |
3750 | } | |
3751 | cName[i] = '/'; | |
3752 | } | |
3753 | } | |
3754 | ||
3755 | } | |
3756 | ||
3757 | int container_rename(LDAP *ldap_handle, char *dn_path, int beforec, char **before, | |
3758 | int afterc, char **after) | |
3759 | { | |
3760 | char dName[256]; | |
3761 | char cName[256]; | |
3762 | char new_cn[128]; | |
3763 | char new_dn_path[256]; | |
3764 | char temp[256]; | |
3765 | char distinguishedName[256]; | |
3766 | char *pPtr; | |
3767 | int rc; | |
3768 | int i; | |
3769 | ||
3770 | memset(cName, '\0', sizeof(cName)); | |
3771 | container_get_name(after[CONTAINER_NAME], cName); | |
3772 | if (!check_string(cName)) | |
3773 | { | |
3774 | com_err(whoami, 0, "invalid LDAP container name %s", cName); | |
3775 | return(AD_INVALID_NAME); | |
3776 | } | |
3777 | ||
3778 | memset(distinguishedName, '\0', sizeof(distinguishedName)); | |
3779 | if (rc = container_get_distinguishedName(ldap_handle, dn_path, distinguishedName, beforec, before)) | |
3780 | return(rc); | |
3781 | if (strlen(distinguishedName) == 0) | |
3782 | { | |
3783 | rc = container_create(ldap_handle, dn_path, afterc, after); | |
3784 | return(rc); | |
3785 | } | |
3786 | ||
3787 | strcpy(temp, after[CONTAINER_NAME]); | |
3788 | pPtr = NULL; | |
3789 | for (i = 0; i < (int)strlen(temp); i++) | |
3790 | { | |
3791 | if (temp[i] == '/') | |
3792 | { | |
3793 | pPtr = &temp[i]; | |
3794 | } | |
3795 | } | |
3796 | if (pPtr != NULL) | |
3797 | (*pPtr) = '\0'; | |
3798 | ||
3799 | container_get_dn(temp, dName); | |
3800 | sprintf(new_dn_path, "%s,%s", dName, dn_path); | |
3801 | sprintf(new_cn, "OU=%s", cName); | |
3802 | ||
3803 | container_check(ldap_handle, dn_path, after[CONTAINER_NAME]); | |
3804 | ||
3805 | if ((rc = ldap_rename_s(ldap_handle, distinguishedName, new_cn, new_dn_path, | |
3806 | TRUE, NULL, NULL)) != LDAP_SUCCESS) | |
3807 | { | |
3808 | com_err(whoami, 0, "couldn't rename container from %s to %s : %s", | |
3809 | before[CONTAINER_NAME], after[CONTAINER_NAME], ldap_err2string(rc)); | |
3810 | return(rc); | |
3811 | } | |
3812 | ||
3813 | memset(dName, '\0', sizeof(dName)); | |
3814 | container_get_dn(after[CONTAINER_NAME], dName); | |
3815 | rc = container_adupdate(ldap_handle, dn_path, dName, "", afterc, after); | |
3816 | return(rc); | |
3817 | } | |
3818 | ||
3819 | int container_delete(LDAP *ldap_handle, char *dn_path, int count, char **av) | |
3820 | { | |
3821 | char distinguishedName[256]; | |
3822 | int rc; | |
3823 | ||
3824 | memset(distinguishedName, '\0', sizeof(distinguishedName)); | |
3825 | if (rc = container_get_distinguishedName(ldap_handle, dn_path, distinguishedName, count, av)) | |
3826 | return(rc); | |
3827 | if (strlen(distinguishedName) == 0) | |
3828 | return(0); | |
3829 | if ((rc = ldap_delete_s(ldap_handle, distinguishedName)) != LDAP_SUCCESS) | |
3830 | { | |
3831 | if (rc == LDAP_NOT_ALLOWED_ON_NONLEAF) | |
3832 | container_move_objects(ldap_handle, dn_path, distinguishedName); | |
3833 | else | |
3834 | com_err(whoami, 0, "unable to delete container %s from AD : %s", | |
3835 | av[CONTAINER_NAME], ldap_err2string(rc)); | |
3836 | } | |
3837 | return(rc); | |
3838 | } | |
3839 | int container_create(LDAP *ldap_handle, char *dn_path, int count, char **av) | |
3840 | { | |
3841 | char *attr_array[3]; | |
3842 | LK_ENTRY *group_base; | |
3843 | int group_count; | |
3844 | LDAPMod *mods[20]; | |
3845 | char *objectClass_v[] = {"top", | |
3846 | "organizationalUnit", | |
3847 | NULL}; | |
3848 | ||
3849 | char *ou_v[] = {NULL, NULL}; | |
3850 | char *name_v[] = {NULL, NULL}; | |
3851 | char *moiraId_v[] = {NULL, NULL}; | |
3852 | char *desc_v[] = {NULL, NULL}; | |
3853 | char *managedBy_v[] = {NULL, NULL}; | |
3854 | char dName[256]; | |
3855 | char cName[256]; | |
3856 | char managedByDN[256]; | |
3857 | char filter[256]; | |
3858 | char temp[256]; | |
3859 | int n; | |
3860 | int i; | |
3861 | int rc; | |
3862 | ||
3863 | memset(filter, '\0', sizeof(filter)); | |
3864 | memset(dName, '\0', sizeof(dName)); | |
3865 | memset(cName, '\0', sizeof(cName)); | |
3866 | memset(managedByDN, '\0', sizeof(managedByDN)); | |
3867 | container_get_dn(av[CONTAINER_NAME], dName); | |
3868 | container_get_name(av[CONTAINER_NAME], cName); | |
3869 | ||
3870 | if ((strlen(cName) == 0) || (strlen(dName) == 0)) | |
3871 | { | |
3872 | com_err(whoami, 0, "invalid LDAP container name %s", cName); | |
3873 | return(AD_INVALID_NAME); | |
3874 | } | |
3875 | ||
3876 | if (!check_string(cName)) | |
3877 | { | |
3878 | com_err(whoami, 0, "invalid LDAP container name %s", cName); | |
3879 | return(AD_INVALID_NAME); | |
3880 | } | |
3881 | ||
3882 | n = 0; | |
3883 | ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD); | |
3884 | name_v[0] = cName; | |
3885 | ADD_ATTR("name", name_v, LDAP_MOD_ADD); | |
3886 | ou_v[0] = cName; | |
3887 | ADD_ATTR("ou", ou_v, LDAP_MOD_ADD); | |
3888 | if (strlen(av[CONTAINER_ROWID]) != 0) | |
3889 | { | |
3890 | moiraId_v[0] = av[CONTAINER_ROWID]; | |
3891 | ADD_ATTR("mitMoiraId", moiraId_v, LDAP_MOD_ADD); | |
3892 | } | |
3893 | if (strlen(av[CONTAINER_DESC]) != 0) | |
3894 | { | |
3895 | desc_v[0] = av[CONTAINER_DESC]; | |
3896 | ADD_ATTR("description", desc_v, LDAP_MOD_ADD); | |
3897 | } | |
3898 | if ((strlen(av[CONTAINER_TYPE]) != 0) && (strlen(av[CONTAINER_ID]) != 0)) | |
3899 | { | |
3900 | if (!strcasecmp(av[CONTAINER_TYPE], "USER")) | |
3901 | { | |
3902 | sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", av[CONTAINER_ID]); | |
3903 | } | |
3904 | if (!strcasecmp(av[CONTAINER_TYPE], "LIST")) | |
3905 | { | |
3906 | sprintf(filter, "(&(objectClass=group)(mitMoiraId=%s))", av[CONTAINER_ID]); | |
3907 | } | |
3908 | if (strlen(filter) != 0) | |
3909 | { | |
3910 | attr_array[0] = "distinguishedName"; | |
3911 | attr_array[1] = NULL; | |
3912 | group_count = 0; | |
3913 | group_base = NULL; | |
3914 | if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array, | |
3915 | &group_base, &group_count)) == LDAP_SUCCESS) | |
3916 | { | |
3917 | if (group_count == 1) | |
3918 | { | |
3919 | strcpy(managedByDN, group_base->value); | |
3920 | managedBy_v[0] = managedByDN; | |
3921 | ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_ADD); | |
3922 | } | |
3923 | linklist_free(group_base); | |
3924 | group_base = NULL; | |
3925 | group_count = 0; | |
3926 | } | |
3927 | } | |
3928 | } | |
3929 | mods[n] = NULL; | |
3930 | ||
3931 | sprintf(temp, "%s,%s", dName, dn_path); | |
3932 | rc = ldap_add_ext_s(ldap_handle, temp, mods, NULL, NULL); | |
3933 | for (i = 0; i < n; i++) | |
3934 | free(mods[i]); | |
3935 | if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS)) | |
3936 | { | |
3937 | com_err(whoami, 0, "couldn't create container %s : %s", | |
3938 | cName, ldap_err2string(rc)); | |
3939 | return(rc); | |
3940 | } | |
3941 | if (rc == LDAP_ALREADY_EXISTS) | |
3942 | { | |
3943 | if (strlen(av[CONTAINER_ROWID]) != 0) | |
3944 | rc = container_adupdate(ldap_handle, dn_path, dName, "", count, av); | |
3945 | } | |
3946 | return(rc); | |
3947 | } | |
3948 | ||
3949 | int container_update(LDAP *ldap_handle, char *dn_path, int beforec, char **before, | |
3950 | int afterc, char **after) | |
3951 | { | |
3952 | char distinguishedName[256]; | |
3953 | int rc; | |
3954 | ||
3955 | memset(distinguishedName, '\0', sizeof(distinguishedName)); | |
3956 | if (rc = container_get_distinguishedName(ldap_handle, dn_path, distinguishedName, afterc, after)) | |
3957 | return(rc); | |
3958 | if (strlen(distinguishedName) == 0) | |
3959 | { | |
3960 | rc = container_create(ldap_handle, dn_path, afterc, after); | |
3961 | return(rc); | |
3962 | } | |
3963 | ||
3964 | container_check(ldap_handle, dn_path, after[CONTAINER_NAME]); | |
3965 | rc = container_adupdate(ldap_handle, dn_path, "", distinguishedName, afterc, after); | |
3966 | ||
3967 | return(rc); | |
3968 | } | |
3969 | ||
3970 | int container_get_distinguishedName(LDAP *ldap_handle, char *dn_path, char *distinguishedName, int count, char **av) | |
3971 | { | |
3972 | char *attr_array[3]; | |
3973 | LK_ENTRY *group_base; | |
3974 | int group_count; | |
3975 | char dName[256]; | |
3976 | char cName[256]; | |
3977 | char filter[512]; | |
3978 | int rc; | |
3979 | ||
3980 | memset(filter, '\0', sizeof(filter)); | |
3981 | memset(dName, '\0', sizeof(dName)); | |
3982 | memset(cName, '\0', sizeof(cName)); | |
3983 | container_get_dn(av[CONTAINER_NAME], dName); | |
3984 | container_get_name(av[CONTAINER_NAME], cName); | |
3985 | ||
3986 | if (strlen(dName) == 0) | |
3987 | { | |
3988 | com_err(whoami, 0, "invalid LDAP container name %s", av[CONTAINER_NAME]); | |
3989 | return(AD_INVALID_NAME); | |
3990 | } | |
3991 | ||
3992 | if (!check_string(cName)) | |
3993 | { | |
3994 | com_err(whoami, 0, "invalid LDAP container name %s", cName); | |
3995 | return(AD_INVALID_NAME); | |
3996 | } | |
3997 | ||
3998 | sprintf(filter, "(&(objectClass=organizationalUnit)(mitMoiraId=%s))", av[CONTAINER_ROWID]); | |
3999 | attr_array[0] = "distinguishedName"; | |
4000 | attr_array[1] = NULL; | |
4001 | group_count = 0; | |
4002 | group_base = NULL; | |
4003 | if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array, | |
4004 | &group_base, &group_count)) == LDAP_SUCCESS) | |
4005 | { | |
4006 | if (group_count == 1) | |
4007 | { | |
4008 | strcpy(distinguishedName, group_base->value); | |
4009 | } | |
4010 | linklist_free(group_base); | |
4011 | group_base = NULL; | |
4012 | group_count = 0; | |
4013 | } | |
4014 | if (strlen(distinguishedName) == 0) | |
4015 | { | |
4016 | sprintf(filter, "(&(objectClass=organizationalUnit)(distinguishedName=%s,%s))", dName, dn_path); | |
4017 | attr_array[0] = "distinguishedName"; | |
4018 | attr_array[1] = NULL; | |
4019 | group_count = 0; | |
4020 | group_base = NULL; | |
4021 | if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array, | |
4022 | &group_base, &group_count)) == LDAP_SUCCESS) | |
4023 | { | |
4024 | if (group_count == 1) | |
4025 | { | |
4026 | strcpy(distinguishedName, group_base->value); | |
4027 | } | |
4028 | linklist_free(group_base); | |
4029 | group_base = NULL; | |
4030 | group_count = 0; | |
4031 | } | |
4032 | } | |
4033 | return(0); | |
4034 | } | |
4035 | ||
4036 | int container_adupdate(LDAP *ldap_handle, char *dn_path, char *dName, | |
4037 | char *distinguishedName, int count, char **av) | |
4038 | { | |
4039 | char *attr_array[5]; | |
4040 | LK_ENTRY *group_base; | |
4041 | LK_ENTRY *pPtr; | |
4042 | LDAPMod *mods[20]; | |
4043 | int group_count; | |
4044 | char filter[512]; | |
4045 | char temp[256]; | |
4046 | char *moiraId_v[] = {NULL, NULL}; | |
4047 | char *desc_v[] = {NULL, NULL}; | |
4048 | char *managedBy_v[] = {NULL, NULL}; | |
4049 | char managedByDN[256]; | |
4050 | char moiraId[64]; | |
4051 | char desc[256]; | |
4052 | int rc; | |
4053 | int i; | |
4054 | int n; | |
4055 | ||
4056 | ||
4057 | strcpy(temp, distinguishedName); | |
4058 | if (strlen(dName) != 0) | |
4059 | sprintf(temp, "%s,%s", dName, dn_path); | |
4060 | ||
4061 | sprintf(filter, "(&(objectClass=organizationalUnit)(distinguishedName=%s))", temp); | |
4062 | if (strlen(av[CONTAINER_ID]) != 0) | |
4063 | sprintf(filter, "(&(objectClass=organizationalUnit)(mitMoiraId=%s))", av[CONTAINER_ROWID]); | |
4064 | attr_array[0] = "mitMoiraId"; | |
4065 | attr_array[1] = "description"; | |
4066 | attr_array[2] = "managedBy"; | |
4067 | attr_array[3] = NULL; | |
4068 | group_count = 0; | |
4069 | group_base = NULL; | |
4070 | if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array, | |
4071 | &group_base, &group_count)) != LDAP_SUCCESS) | |
4072 | { | |
4073 | com_err(whoami, 0, "couldn't retreive container info for %s : %s", | |
4074 | av[CONTAINER_NAME], ldap_err2string(rc)); | |
4075 | return(rc); | |
4076 | } | |
4077 | memset(managedByDN, '\0', sizeof(managedByDN)); | |
4078 | memset(moiraId, '\0', sizeof(moiraId)); | |
4079 | memset(desc, '\0', sizeof(desc)); | |
4080 | pPtr = group_base; | |
4081 | while (pPtr) | |
4082 | { | |
4083 | if (!strcasecmp(pPtr->attribute, "description")) | |
4084 | strcpy(desc, pPtr->value); | |
4085 | if (!strcasecmp(pPtr->attribute, "managedBy")) | |
4086 | strcpy(managedByDN, pPtr->value); | |
4087 | if (!strcasecmp(pPtr->attribute, "mitMoiraId")) | |
4088 | strcpy(moiraId, pPtr->value); | |
4089 | pPtr = pPtr->next; | |
4090 | } | |
4091 | linklist_free(group_base); | |
4092 | group_base = NULL; | |
4093 | group_count = 0; | |
4094 | ||
4095 | n = 0; | |
4096 | if (strlen(av[CONTAINER_ROWID]) != 0) | |
4097 | { | |
4098 | moiraId_v[0] = av[CONTAINER_ROWID]; | |
4099 | ADD_ATTR("mitMoiraId", moiraId_v, LDAP_MOD_REPLACE); | |
4100 | } | |
4101 | if (strlen(av[CONTAINER_DESC]) != 0) | |
4102 | { | |
4103 | desc_v[0] = av[CONTAINER_DESC]; | |
4104 | ADD_ATTR("description", desc_v, LDAP_MOD_REPLACE); | |
4105 | } | |
4106 | else | |
4107 | { | |
4108 | if (strlen(desc) != 0) | |
4109 | { | |
4110 | desc_v[0] = NULL; | |
4111 | ADD_ATTR("description", desc_v, LDAP_MOD_REPLACE); | |
4112 | } | |
4113 | } | |
4114 | if ((strlen(av[CONTAINER_TYPE]) != 0) && (strlen(av[CONTAINER_ID]) != 0)) | |
4115 | { | |
4116 | if (!strcasecmp(av[CONTAINER_TYPE], "USER")) | |
4117 | { | |
4118 | sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", av[CONTAINER_ID]); | |
4119 | } | |
4120 | if (!strcasecmp(av[CONTAINER_TYPE], "LIST")) | |
4121 | { | |
4122 | sprintf(filter, "(&(objectClass=group)(mitMoiraId=%s))", av[CONTAINER_ID]); | |
4123 | } | |
4124 | if (strlen(filter) != 0) | |
4125 | { | |
4126 | attr_array[0] = "distinguishedName"; | |
4127 | attr_array[1] = NULL; | |
4128 | group_count = 0; | |
4129 | group_base = NULL; | |
4130 | if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array, | |
4131 | &group_base, &group_count)) == LDAP_SUCCESS) | |
4132 | { | |
4133 | if (group_count == 1) | |
4134 | { | |
4135 | strcpy(managedByDN, group_base->value); | |
4136 | managedBy_v[0] = managedByDN; | |
4137 | ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_REPLACE); | |
4138 | } | |
4139 | else | |
4140 | { | |
4141 | if (strlen(managedByDN) != 0) | |
4142 | { | |
4143 | managedBy_v[0] = NULL; | |
4144 | ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_REPLACE); | |
4145 | } | |
4146 | } | |
4147 | linklist_free(group_base); | |
4148 | group_base = NULL; | |
4149 | group_count = 0; | |
4150 | } | |
4151 | } | |
4152 | else | |
4153 | { | |
4154 | if (strlen(managedByDN) != 0) | |
4155 | { | |
4156 | managedBy_v[0] = NULL; | |
4157 | ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_REPLACE); | |
4158 | } | |
4159 | } | |
4160 | } | |
4161 | mods[n] = NULL; | |
4162 | if (n == 0) | |
4163 | return(LDAP_SUCCESS); | |
4164 | ||
4165 | strcpy(temp, distinguishedName); | |
4166 | if (strlen(dName) != 0) | |
4167 | sprintf(temp, "%s,%s", dName, dn_path); | |
4168 | rc = ldap_modify_s(ldap_handle, temp, mods); | |
4169 | for (i = 0; i < n; i++) | |
4170 | free(mods[i]); | |
4171 | if (rc != LDAP_SUCCESS) | |
4172 | { | |
4173 | com_err(whoami, 0, "couldn't modify container info for %s : %s", | |
4174 | av[CONTAINER_NAME], ldap_err2string(rc)); | |
4175 | return(rc); | |
4176 | } | |
4177 | return(rc); | |
4178 | } | |
4179 | ||
4180 | int container_move_objects(LDAP *ldap_handle, char *dn_path, char *dName) | |
4181 | { | |
4182 | char *attr_array[3]; | |
4183 | LK_ENTRY *group_base; | |
4184 | LK_ENTRY *pPtr; | |
4185 | int group_count; | |
4186 | char filter[512]; | |
4187 | char new_cn[128]; | |
4188 | char temp[256]; | |
4189 | int rc; | |
4190 | int NumberOfEntries = 10; | |
4191 | int i; | |
4192 | int count; | |
4193 | ||
4194 | rc = ldap_set_option(ldap_handle, LDAP_OPT_SIZELIMIT, &NumberOfEntries); | |
4195 | ||
4196 | for (i = 0; i < 3; i++) | |
4197 | { | |
4198 | memset(filter, '\0', sizeof(filter)); | |
4199 | if (i == 0) | |
4200 | { | |
4201 | strcpy(filter, "(!(|(objectClass=computer)(objectClass=organizationalUnit)))"); | |
4202 | attr_array[0] = "cn"; | |
4203 | attr_array[1] = NULL; | |
4204 | } | |
4205 | else if (i == 1) | |
4206 | { | |
4207 | strcpy(filter, "(objectClass=computer)"); | |
4208 | attr_array[0] = "cn"; | |
4209 | attr_array[1] = NULL; | |
4210 | } | |
4211 | else | |
4212 | { | |
4213 | strcpy(filter, "(objectClass=organizationalUnit)"); | |
4214 | attr_array[0] = "ou"; | |
4215 | attr_array[1] = NULL; | |
4216 | } | |
4217 | ||
4218 | while (1) | |
4219 | { | |
4220 | if ((rc = linklist_build(ldap_handle, dName, filter, attr_array, | |
4221 | &group_base, &group_count)) != LDAP_SUCCESS) | |
4222 | { | |
4223 | break; | |
4224 | } | |
4225 | if (group_count == 0) | |
4226 | break; | |
4227 | pPtr = group_base; | |
4228 | while(pPtr) | |
4229 | { | |
4230 | if (!strcasecmp(pPtr->attribute, "cn")) | |
4231 | { | |
4232 | sprintf(new_cn, "cn=%s", pPtr->value); | |
4233 | if (i == 0) | |
4234 | sprintf(temp, "%s,%s", orphans_other_ou, dn_path); | |
4235 | if (i == 1) | |
4236 | sprintf(temp, "%s,%s", orphans_machines_ou, dn_path); | |
4237 | count = 1; | |
4238 | while (1) | |
4239 | { | |
4240 | rc = ldap_rename_s(ldap_handle, pPtr->dn, new_cn, temp, | |
4241 | TRUE, NULL, NULL); | |
4242 | if (rc == LDAP_ALREADY_EXISTS) | |
4243 | { | |
4244 | sprintf(new_cn, "cn=%s_%d", pPtr->value, count); | |
4245 | ++count; | |
4246 | } | |
4247 | else | |
4248 | break; | |
4249 | } | |
4250 | } | |
4251 | else if (!strcasecmp(pPtr->attribute, "ou")) | |
4252 | { | |
4253 | rc = ldap_delete_s(ldap_handle, pPtr->dn); | |
4254 | } | |
4255 | pPtr = pPtr->next; | |
4256 | } | |
4257 | linklist_free(group_base); | |
4258 | group_base = NULL; | |
4259 | group_count = 0; | |
4260 | } | |
4261 | } | |
4262 | return(0); | |
4263 | } |