]> andersk Git - moira.git/blob - incremental/winad/winad.c
Fixes for list renaming.
[moira.git] / incremental / winad / winad.c
1 /* $Header$
2 /* test parameters for creating a user account - done 
3  * users 10 10 a_chen 31275 sh cmd Lastname Firstname Middlename 0 950000000 STAFF a_chen 31275 sh cmd Lastname Firstname Middlename 2 950000000 STAFF
4  * users 10 10 a_chen 31275 sh cmd Lastname Firstname Middlename 2 950000000 STAFF a_chen 31275 sh cmd Lastname Firstname Middlename 1 950000000 STAFF
5  *   login, unix_uid, shell, winconsoleshell, last, first, middle, status, clearid, type
6  *
7  * test parameters for deactivating/deleting a user account - done
8  * users 10 10 a_chen 31275 sh cmd Lastname Firstname Middlename 1 950000000 STAFF a_chen 31275 sh cmd Lastname Firstname Middlename 3 950000000 STAFF 
9  * users 10 10 a_chen 31275 sh cmd Lastname Firstname Middlename 2 950000000 STAFF a_chen 31275 sh cmd Lastname Firstname Middlename 3 950000000 STAFF 
10  *   login, unix_uid, shell, winconsoleshell, last, first, middle, status, clearid, type
11  * comment: clearid is the MIT ID
12  *
13  * test parameters for reactivating a user account - done
14  * users 10 10 testacc 31275 sh cmd Lastname Firstname Middlename 3 950000000 STAFF testacc 31275 sh cmd Lastname Firstname Middlename 2 950000000 STAFF 
15  *   login, unix_uid, shell, winconsoleshell, last, first, middle, status, clearid, type
16  *
17  * test parameters for updating user account info - done
18  * users 10 10 testacc 31275 sh cmd Lastname Firstname Middlename 2 950000000 STAFF testacc 31275 sh cmd newLastname Firstname Middlename 2 950000000 STAFF 
19  * users 10 10 6_d0006 950 sh cmd Lastname Firstname Middlename 1 900012345 STAFF 6_d0006 950 sh cmd Lastname Firstname Middlename 1 950012345 STAFF
20  *   login, unix_uid, shell, winconsoleshell, last, first, middle, status, clearid, type
21  *   currently, if the unix_id doesn't change, only the U_UID or U_MITID fields will be updated
22  *
23  * test parameters for changing user name - testing
24  * users 10 10 a_chen 31275 sh cmd Lastname Firstname Middlename 2 950000000 STAFF testacc1 31275 sh cmd Lastname Firstname Middlename 2 950000000 STAFF
25  * users 10 10 testacc 31275 sh cmd Lastname Firstname Middlename 1 950000000 STAFF testacc1 31275 sh cmd Lastname Firstname Middlename 1 950000000 STAFF
26  *   login, unix_uid, shell, winconsoleshell, last, first, middle, status, clearid, type
27  *
28  * test parameters for add member to group/list - done
29  * imembers 0 10 pismere-team USER dtanner 1 1 0 1 1 -1 1
30  *   list_name, user_type, name, active, publicflg, hidden, maillist, grouplist, gid
31  *
32  * test parameters for remove member from group/list - done
33  * imembers 10 0 pismere-team USER dtanner 1 1 0 1 1 -1 1
34  *   list_name, user_type, name, active, publicflg, hidden, maillist, grouplist, gid
35  *
36  * test parameters for creating and/or populating a group/list - done
37  * list 0 10 pismere-team 1 1 0 1 0 -1 USER 95260 description
38  *   name, active, publicflg, hidden, maillist, grouplist, gid, acl_type, acl_id, description
39  * 
40  * test parameters for deleting a group/list - done
41  * list 10 0 pismere-team 1 1 0 1 0 -1 USER 95260 description
42  *   name, active, publicflg, hidden, maillist, grouplist, gid, acl_type, acl_id, description
43  *
44  * test parameters for renaming a group/list - done
45  *  list 10 10 adtestlist 1 1 0 1 0 -1 USER 95260 description pismere-team 1 1 0 1 1 -1 USER 95260 description
46  *  list 10 10 pismere-team 1 1 0 1 1 -1 USER 95260 description adtestlist1 1 1 0 1 0 -1 USER 95260 description
47  *   name, active, publicflg, hidden, maillist, grouplist, gid, acl_type, acl_id, description
48  *
49  * test parameters for adding a file system - done
50  *   filesys 0 11 addusr5 AFS ATHENA.MIT.EDU /afs/athena.mit.edu/user/a/d/addusr5 /mit/addusr5 w UserLocker addusr5 wheel 1 HOMEDIR
51  *
52  * test parameters for deleting a file system - done
53  *   filesys 11 0 addusr8 AFS ATHENA.MIT.EDU /afs/athena.mit.edu/user/a/d/addusr8 /mit/addusr8 w none dtanner wheel 1 HOMEDIR
54 */
55 #include <mit-copyright.h>
56 #ifdef _WIN32
57 #include <windows.h>
58 #include <stdlib.h>
59 #include <malloc.h>
60 #include <lmaccess.h>
61 #endif
62 #include <hesiod.h>
63 #include <string.h>
64 #include <ldap.h>
65 #include <stdio.h>
66 #include <moira.h>
67 #include <moira_site.h>
68 #include <mrclient.h>
69 #include <krb5.h>
70 #include <krb.h>
71 #include <gsssasl.h>
72 #include <gssldap.h>
73 #include "kpasswd.h"
74
75 #ifdef _WIN32
76 #ifndef ECONNABORTED
77 #define ECONNABORTED WSAECONNABORTED
78 #endif
79 #ifndef ECONNREFUSED
80 #define ECONNREFUSED WSAECONNREFUSED
81 #endif
82 #ifndef EHOSTUNREACH
83 #define EHOSTUNREACH WSAEHOSTUNREACH
84 #endif
85 #define krb5_xfree free
86 #define F_OK 0
87 #define sleep(A) Sleep(A * 1000);
88 #endif /* _WIN32 */
89
90 #ifndef _WIN32
91 #include <sys/types.h>
92 #include <netinet/in.h>
93 #include <arpa/nameser.h>
94 #include <resolv.h>
95 #include <sys/utsname.h>
96 #include <unistd.h>
97
98 #define WINADCFG "/moira/winad/winad.cfg"
99 #define strnicmp(A,B,C) strncasecmp(A,B,C)
100 #define UCHAR unsigned char
101
102 #define UF_SCRIPT               0x0001
103 #define UF_ACCOUNTDISABLE       0x0002
104 #define UF_HOMEDIR_REQUIRED     0x0008
105 #define UF_LOCKOUT              0x0010
106 #define UF_PASSWD_NOTREQD       0x0020
107 #define UF_PASSWD_CANT_CHANGE   0x0040
108 #define UF_DONT_EXPIRE_PASSWD   0x10000
109
110 #define UF_TEMP_DUPLICATE_ACCOUNT       0x0100
111 #define UF_NORMAL_ACCOUNT               0x0200
112 #define UF_INTERDOMAIN_TRUST_ACCOUNT    0x0800
113 #define UF_WORKSTATION_TRUST_ACCOUNT    0x1000
114 #define UF_SERVER_TRUST_ACCOUNT         0x2000
115
116 #ifndef BYTE
117 #define BYTE unsigned char
118 #endif
119 typedef unsigned int DWORD;
120 typedef unsigned long ULONG;
121
122 typedef struct _GUID
123 {
124   unsigned long Data1;
125   unsigned short Data2;
126   unsigned short Data3;
127   unsigned char Data4[8];
128 } GUID;
129
130 typedef struct _SID_IDENTIFIER_AUTHORITY { 
131   BYTE Value[6]; 
132 } SID_IDENTIFIER_AUTHORITY, *PSID_IDENTIFIER_AUTHORITY; 
133
134 typedef struct _SID {
135   BYTE  Revision;
136   BYTE  SubAuthorityCount;
137   SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
138   DWORD SubAuthority[512];
139 } SID;
140 #endif/*!WIN32*/
141
142 #ifndef WINADCFG
143 #define WINADCFG "winad.cfg"
144 #endif
145
146 #define AFS "/afs/"
147 #define WINAFS "\\\\afs\\all\\"
148
149 #define ADS_GROUP_TYPE_GLOBAL_GROUP         0x00000002
150 #define ADS_GROUP_TYPE_DOMAIN_LOCAL_GROUP   0x00000004
151 #define ADS_GROUP_TYPE_LOCAL_GROUP          0x00000004
152 #define ADS_GROUP_TYPE_UNIVERSAL_GROUP      0x00000008
153 #define ADS_GROUP_TYPE_SECURITY_ENABLED     0x80000000
154
155 #define QUERY_VERSION -1
156 #define PRIMARY_REALM "ATHENA.MIT.EDU"
157
158 #define SUBSTITUTE  1
159 #define REPLACE     2
160
161 #define USERS         0
162 #define GROUPS        1
163
164 #define MEMBER_ADD          1
165 #define MEMBER_REMOVE       2
166 #define MEMBER_CHANGE_NAME  3
167 #define MEMBER_ACTIVATE     4
168 #define MEMBER_DEACTIVATE   5
169 #define MEMBER_CREATE       6
170
171 #define MOIRA_ALL       0x0
172 #define MOIRA_USERS     0x1
173 #define MOIRA_KERBEROS  0x2
174 #define MOIRA_STRINGS   0x4
175 #define MOIRA_LISTS     0x8
176
177 typedef struct lk_entry {
178   int     op;
179   int     length;
180   int     ber_value;
181   char    *dn;
182   char    *attribute;
183   char    *value;
184   char    *member;
185   char    *type;
186   char    *list;
187   struct  lk_entry *next;
188 } LK_ENTRY;
189
190 #define STOP_FILE "/moira/winad/nowinad"
191 #define file_exists(file) (access((file), F_OK) == 0)
192
193 #define LDAP_BERVAL struct berval
194 #define MAX_SERVER_NAMES 32
195
196 #define ADD_ATTR(t, v, o)               \
197   mods[n] = malloc(sizeof(LDAPMod));    \
198   mods[n]->mod_op = o;  \
199   mods[n]->mod_type = t;                \
200   mods[n++]->mod_values = v
201
202 LK_ENTRY *member_base = NULL;
203 LK_ENTRY *sid_base = NULL;
204 LK_ENTRY **sid_ptr = NULL;
205 static char tbl_buf[1024];
206 char  kerberos_ou[] = "OU=kerberos, OU=moira";
207 char  contact_ou[] = "OU=strings, OU=moira";
208 char  user_ou[] = "OU=users, OU=moira";
209 char  group_ou_distribution[] = "OU=mail, OU=lists, OU=moira";
210 char  group_ou_root[] = "OU=lists, OU=moira";
211 char  group_ou_security[] = "OU=group, OU=lists, OU=moira";
212 char  group_ou_neither[] = "OU=special, OU=lists, OU=moira";
213 char  group_ou_both[] = "OU=mail, OU=group, OU=lists, OU=moira";
214 char *whoami;
215 char ldap_domain[256];
216 int  mr_connections = 0;
217 int  callback_rc;
218 int  UserReactivate = 0;
219 char default_server[256];
220 static char tbl_buf[1024];
221
222 extern int set_password(char *user, char *password, char *domain);
223
224 void AfsToWinAfs(char* path, char* winPath);
225 int ad_connect(LDAP **ldap_handle, char *ldap_domain, char *dn_path, 
226                char *Win2kPassword, char *Win2kUser, char *default_server,
227                int connect_to_kdc);
228 void ad_kdc_disconnect();
229 void check_winad(void);
230 int filesys_process(LDAP *ldap_handle, char *dn_path, char *fs_name, 
231                     char *fs_type, char *fs_pack, int operation);
232 int get_group_membership(char *group_membership, char *group_ou, 
233                          int *security_flag, char **av);
234 int process_lists(int ac, char **av, void *ptr);
235 int user_create(int ac, char **av, void *ptr);
236 int user_change_status(LDAP *ldap_handle, char *dn_path, char *user_name, int operation);
237 int user_delete(LDAP *ldap_handle, char *dn_path, char *u_name);
238 int user_rename(LDAP *ldap_handle, char *dn_path, char *before_user_name, 
239                 char *user_name, char *Uid, char *MitId, int State);
240 int user_update(LDAP *ldap_handle, char *dn_path, char *user_name,
241                 char *uid, char *MitId);
242 int contact_create(LDAP *ld, char *bind_path, char *user, char *group_ou);
243 int group_create(int ac, char **av, void *ptr);
244 int group_delete(LDAP *ldap_handle, char *dn_path, 
245                  char *group_name, char *group_membership);
246 int group_rename(LDAP *ldap_handle, char *dn_path, 
247                  char *before_group_name, char *before_group_membership, 
248                  char *before_group_ou, int before_security_flag, char *before_desc,
249                  char *after_group_name, char *after_group_membership, 
250                  char *after_group_ou, int after_security_flag, char *after_desc);
251 int member_list_build(int ac, char **av, void *ptr);
252 int member_add(LDAP *ldap_handle, char *dn_path, char *group_name, 
253                         char *group_ou, char *group_membership, 
254                         char *user_name, char *pUserOu);
255 int member_remove(LDAP *ldap_handle, char *dn_path, char *group_name, 
256                   char *group_ou, char *group_membership, char *user_name,
257                   char *pUserOu);
258 int sid_update(LDAP *ldap_handle, char *dn_path);
259 int check_string(char *s);
260 void convert_b_to_a(char *string, UCHAR *binary, int length);
261 int mr_connect_cl(char *server, char *client, int version, int auth);
262
263 void do_filesys(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
264              char **before, int beforec, char **after, int afterc);
265 void do_list(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
266              char **before, int beforec, char **after, int afterc);
267 void do_user(LDAP *ldap_handle, char *dn_path, char *ldap_hostname, 
268              char **before, int beforec, char **after, int afterc);
269 void do_member(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
270                char **before, int beforec, char **after, int afterc);
271 int linklist_create_entry(char *attribute, char *value,
272                           LK_ENTRY **linklist_entry);
273 int linklist_build(LDAP *ldap_handle, char *dn_path, char *search_exp, 
274                    char **attr_array, LK_ENTRY **linklist_base, 
275                    int *linklist_count);
276 void linklist_free(LK_ENTRY *linklist_base);
277
278 int retrieve_attributes(LDAP *ldap_handle, LDAPMessage *ldap_entry, 
279                         char *distinguished_name, LK_ENTRY **linklist_current);
280 int retrieve_entries(LDAP *ldap_handle, LDAPMessage *ldap_entry, 
281                      LK_ENTRY **linklist_base, int *linklist_count);
282 int retrieve_values(LDAP *ldap_handle, LDAPMessage *ldap_entry, 
283                     char *Attribute, char *distinguished_name, 
284                     LK_ENTRY **linklist_current);
285
286 int construct_newvalues(LK_ENTRY *linklist_base, int modvalue_count, 
287                         char *oldValue, char *newValue,
288                         char ***modvalues, int type);
289 void free_values(char **modvalues);
290
291 int convert_domain_to_dn(char *domain, char **bind_path);
292 void get_distinguished_name(LDAP *ldap_handle, LDAPMessage *ldap_entry, 
293                             char *distinguished_name);
294 int moira_disconnect(void);
295 int moira_connect(void);
296 void print_to_screen(const char *fmt, ...);
297
298 int main(int argc, char **argv)
299 {
300   unsigned long   rc;
301   int             beforec;
302   int             afterc;
303   int             i;
304   char            *table;
305   char            **before;
306   char            **after;
307   LDAP            *ldap_handle;
308   FILE            *fptr;
309   char            dn_path[256];
310
311   whoami = ((whoami = (char *)strrchr(argv[0], '/')) ? whoami+1 : argv[0]);
312
313   if (argc < 4)
314     {
315       com_err(whoami, 0, "%s", "argc < 4");
316       exit(1);
317     }
318   beforec = atoi(argv[2]);
319   afterc = atoi(argv[3]);
320
321   if (argc < (4 + beforec + afterc))
322     {
323       com_err(whoami, 0, "%s", "argc < (4 + breforec + afterc)");
324       exit(1);
325     }
326
327   table = argv[1];
328   before = &argv[4];
329   after = &argv[4 + beforec];
330
331   for (i = 1; i < argc; i++)
332     {
333       strcat(tbl_buf, argv[i]);
334       strcat(tbl_buf, " ");
335     }
336   com_err(whoami, 0, "%s", tbl_buf);
337
338   check_winad();
339
340   memset(ldap_domain, '\0', sizeof(ldap_domain));
341   if ((fptr = fopen(WINADCFG, "r")) != NULL)
342     {
343       fread(ldap_domain, sizeof(char), sizeof(ldap_domain), fptr);
344       fclose(fptr);
345     }
346   if (strlen(ldap_domain) == 0)
347     strcpy(ldap_domain, "win.mit.edu");
348   initialize_sms_error_table();
349   initialize_krb_error_table();
350
351   memset(default_server, '\0', sizeof(default_server));
352   memset(dn_path, '\0', sizeof(dn_path));
353   if (ad_connect(&ldap_handle, ldap_domain, dn_path, "", "", default_server, 1))
354     {
355       com_err(whoami, 0, "cannot connect to any server in domain %s", ldap_domain);
356       exit(1);
357     }
358
359   for (i = 0; i < (int)strlen(table); i++)
360     table[i] = tolower(table[i]);
361   if (!strcmp(table, "users"))
362     do_user(ldap_handle, dn_path, ldap_domain, before, beforec, after,
363             afterc);
364   else if (!strcmp(table, "list"))
365     do_list(ldap_handle, dn_path, ldap_domain, before, beforec, after,
366             afterc);
367   else if (!strcmp(table, "imembers"))
368     do_member(ldap_handle, dn_path, ldap_domain, before, beforec, after,
369               afterc);
370   else if (!strcmp(table, "filesys"))
371     do_filesys(ldap_handle, dn_path, ldap_domain, before, beforec, after,
372                afterc);
373 /*
374   else if (!strcmp(table, "quota"))
375     do_quota(before, beforec, after, afterc);
376 */
377
378   ad_kdc_disconnect();
379   rc = ldap_unbind_s(ldap_handle);
380   exit(0);
381 }
382
383 void do_filesys(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
384              char **before, int beforec, char **after, int afterc)
385 {
386   long  rc;
387   char  *av[3];
388   char  *call_args[7];
389   int   acreate;
390   int   atype;
391   int   bcreate;
392   int   btype;
393   int   abort_flag;
394
395   abort_flag = 0;
396
397   if (afterc < FS_CREATE)
398     atype = acreate = 0;
399   else
400     {
401       atype = !strcmp(after[FS_TYPE], "AFS");
402       acreate = atoi(after[FS_CREATE]);
403     }
404
405   if (beforec < FS_CREATE)
406     {
407       if (acreate == 0 || atype == 0)
408         goto cleanup;
409       com_err(whoami, 0, "Processing filesys %s", after[FS_NAME]);
410       abort_flag = 0;
411       while (1)
412       {
413         if ((rc = filesys_process(ldap_handle, dn_path, after[FS_NAME], 
414                     after[FS_TYPE], after[FS_PACK], LDAP_MOD_ADD)) != LDAP_NO_SUCH_OBJECT)
415           {
416             if (rc != LDAP_SUCCESS)
417               com_err(whoami, 0, "Couldn't process filesys %s", after[FS_NAME]);
418             break;
419           }
420         if (abort_flag == 1)
421           break;
422         sleep(1);
423         abort_flag = 1;
424         if (rc = moira_connect())
425           {
426             critical_alert("AD incremental",
427                            "Error contacting Moira server : %s",
428                            error_message(rc));
429             return;
430           }
431         av[0] = after[FS_NAME];
432         call_args[0] = (char *)ldap_handle;
433         call_args[1] = dn_path;
434         call_args[2] = (char *)MEMBER_ACTIVATE;
435         call_args[3] = NULL;
436         sid_base = NULL;
437         sid_ptr = &sid_base;
438         callback_rc = 0;
439         if (rc = mr_query("get_user_account_by_login", 1, av, user_create,
440                           call_args))
441           {
442             moira_disconnect();
443             com_err(whoami, 0, "Couldn't process filesys %s", after[FS_NAME]);
444             break;
445           }
446         if (callback_rc)
447           {
448             moira_disconnect();
449             com_err(whoami, 0, "Couldn't process filesys %s", after[FS_NAME]);
450             break;
451           }
452         if (sid_base != NULL)
453           {
454             sid_update(ldap_handle, dn_path);
455             linklist_free(sid_base);
456             sid_base = NULL;
457           }
458         moira_disconnect();
459       }
460       goto cleanup;
461     }
462
463   btype = !strcmp(before[FS_TYPE], "AFS");
464   bcreate = atoi(before[FS_CREATE]);
465   if (afterc < FS_CREATE)
466     {
467       if (btype && bcreate)
468         {
469           if (rc = filesys_process(ldap_handle, dn_path, before[FS_NAME], 
470                       before[FS_TYPE], before[FS_PACK], LDAP_MOD_DELETE))
471             {
472               com_err(whoami, 0, "Couldn't delete filesys %s", before[FS_NAME]);
473             }
474         }
475       return;
476     }
477
478   if (!acreate)
479     return;
480
481   if (!atype && !btype)
482     {
483       if (strcmp(before[FS_TYPE], "ERR") || strcmp(after[FS_TYPE], "ERR"))
484         {
485           com_err(whoami, 0, "Filesystem %s or %s is not AFS",
486                   before[FS_NAME], after[FS_NAME]);
487           return;
488         }
489     }
490   com_err(whoami, 0, "Processing filesys %s", after[FS_NAME]);
491   abort_flag = 0;
492   while (1)
493   {
494     if ((rc = filesys_process(ldap_handle, dn_path, after[FS_NAME], 
495                     after[FS_TYPE], after[FS_PACK], LDAP_MOD_ADD)) != LDAP_NO_SUCH_OBJECT)
496       {
497         if (rc != LDAP_SUCCESS)
498           com_err(whoami, 0, "Couldn't process filesys %s", after[FS_NAME]);
499         break;
500       }
501     if (abort_flag == 1)
502       break;
503     sleep(1);
504     abort_flag = 1;
505     if (rc = moira_connect())
506       {
507         critical_alert("AD incremental",
508                        "Error contacting Moira server : %s",
509                        error_message(rc));
510         return;
511       }
512     av[0] = after[FS_NAME];
513     call_args[0] = (char *)ldap_handle;
514     call_args[1] = dn_path;
515     call_args[2] = (char *)MEMBER_ACTIVATE;
516     call_args[3] = NULL;
517     sid_base = NULL;
518     sid_ptr = &sid_base;
519     callback_rc = 0;
520     if (rc = mr_query("get_user_account_by_login", 1, av, user_create,
521                       call_args))
522       {
523         moira_disconnect();
524         com_err(whoami, 0, "Couldn't process filesys %s", after[FS_NAME]);
525         break;
526       }
527     if (callback_rc)
528       {
529         moira_disconnect();
530         com_err(whoami, 0, "Couldn't process filesys %s", after[FS_NAME]);
531         break;
532       }
533     if (sid_base != NULL)
534       {
535         sid_update(ldap_handle, dn_path);
536         linklist_free(sid_base);
537         sid_base = NULL;
538       }
539     moira_disconnect();
540   }
541
542 cleanup:
543   return;
544 }
545 void do_list(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
546              char **before, int beforec, char **after, int afterc)
547 {
548   int   agid;
549   int   bgid;
550   int   ahide;
551   int   bhide;
552   int   apublic;
553   int   bpublic;
554   int   bgroup;
555   int   agroup;
556   int   amaillist;
557   int   bmaillist;
558   int   bstatus;
559   int   astatus;
560   long  rc;
561   char  *av[3];
562   char  *call_args[7];
563   char  group_membership[1];
564   int   security_flag;
565   char  group_ou[256];
566   char  before_group_membership[1];
567   int   before_security_flag;
568   char  before_group_ou[256];
569   char  *pUserOu;
570   LK_ENTRY *ptr = NULL;
571
572   if (beforec == 0 && afterc == 0)
573     return;
574
575   astatus = bstatus = 0;
576   ahide = bhide = 0;
577   apublic = bpublic = 0;
578   amaillist = bmaillist = 0;
579   agid = 0;
580   bgid = 0;
581
582   if (beforec > L_GID && atoi(before[L_ACTIVE]))
583     {
584       bgid = atoi(before[L_GID]);
585       bstatus = atoi(before[L_ACTIVE]);
586       bhide = atoi(before[L_HIDDEN]);
587       bpublic = atoi(before[L_PUBLIC]);
588       bmaillist = atoi(before[L_MAILLIST]);
589       bgroup = atoi(before[L_GROUP]);
590       before_security_flag = 0;
591       memset(before_group_ou, '\0', sizeof(before_group_ou));
592       memset(before_group_membership, '\0', sizeof(before_group_membership));
593       get_group_membership(before_group_membership, before_group_ou, &before_security_flag, before);
594     }
595   if (afterc > L_GID && atoi(after[L_ACTIVE]))
596     {
597       agid = atoi(after[L_GID]);
598       astatus = atoi(after[L_ACTIVE]);
599       ahide = atoi(after[L_HIDDEN]);
600       apublic = atoi(after[L_PUBLIC]);
601       amaillist = atoi(after[L_MAILLIST]);
602       agroup = atoi(after[L_GROUP]);
603       security_flag = 0;
604       memset(group_ou, '\0', sizeof(group_ou));
605       memset(group_membership, '\0', sizeof(group_membership));
606       get_group_membership(group_membership, group_ou, &security_flag, after);
607     }
608   if (agid == 0 && bgid == 0)
609     return;
610
611   if (agid && bgid)
612     {
613       if ((strcmp(after[L_NAME], before[L_NAME])) || 
614           ((!strcmp(after[L_NAME], before[L_NAME])) && 
615            (strcmp(before_group_ou, group_ou))))
616         {
617           if (astatus && bstatus)
618             {
619               com_err(whoami, 0, "Changing list name from %s to %s",
620                       before[L_NAME], after[L_NAME]);
621               if ((strlen(before_group_ou) == 0) || (strlen(before_group_membership) == 0) ||
622                   (strlen(group_ou) == 0) || (strlen(group_membership) == 0))
623                 {
624                   com_err(whoami, 0, "%s", "couldn't find the group OU's");
625                   return;
626                 }
627               if ((rc = group_rename(ldap_handle, dn_path, 
628                                      before[L_NAME], before_group_membership, 
629                                      before_group_ou, before_security_flag, before[9],
630                                      after[L_NAME], group_membership, 
631                                      group_ou, security_flag, after[9])) != LDAP_NO_SUCH_OBJECT)
632                 {
633                   if (rc != LDAP_SUCCESS)
634                     com_err(whoami, 0, "Could not change list name from %s to %s",
635                                     before[L_NAME], 
636                                     after[L_NAME]);
637                   return;
638                 }
639               bgid = 0;
640             }
641           if (!agid)
642             return;
643         }
644       else
645         bgid = 0;
646     }
647
648   if (bgid)
649     {
650       if ((strlen(before_group_ou) == 0) || (strlen(before_group_membership) == 0))
651         {
652           com_err(whoami, 0, "couldn't find the group OU for group %s", before[L_NAME]);
653           return;
654         }
655       com_err(whoami, 0, "Deleting group %s", before[L_NAME]);
656       rc = group_delete(ldap_handle, dn_path, before[L_NAME], before_group_membership);
657       return;
658     }
659   if (agid)
660     {
661       com_err(whoami, 0, "Creating group %s", after[L_NAME]);
662
663       if (rc = moira_connect())
664         {
665           critical_alert("AD incremental",
666                          "Error contacting Moira server : %s",
667                          error_message(rc));
668           return;
669         }
670
671       av[0] = after[L_NAME];
672       call_args[0] = (char *)ldap_handle;
673       call_args[1] = dn_path;
674       call_args[2] = after[L_NAME];
675       call_args[3] = (char *)(MOIRA_USERS | MOIRA_KERBEROS | MOIRA_STRINGS);
676       call_args[4] = NULL;
677       sid_base = NULL;
678       sid_ptr = &sid_base;
679       callback_rc = 0;
680       if (rc = mr_query("get_list_info", 1, av, group_create, call_args))
681         {
682           moira_disconnect();
683           com_err(whoami, 0, "Couldn't create list %s : %s", after[L_NAME], error_message(rc));
684           return;
685         }
686       if (callback_rc)
687         {
688           moira_disconnect();
689           com_err(whoami, 0, "Couldn't create list %s", after[L_NAME]);
690           return;
691         }
692
693       if (sid_base != NULL)
694         {
695           sid_update(ldap_handle, dn_path);
696           linklist_free(sid_base);
697           sid_base = NULL;
698         }
699
700       sleep(1);
701       com_err(whoami, 0, "Populating group %s", after[L_NAME]);
702       av[0] = after[L_NAME];
703       call_args[0] = (char *)ldap_handle;
704       call_args[1] = dn_path;
705       call_args[2] = after[L_NAME];
706       call_args[3] = (char *)(MOIRA_USERS | MOIRA_KERBEROS | MOIRA_STRINGS);
707       call_args[4] = NULL;
708       member_base = NULL;
709       if (rc = mr_query("get_end_members_of_list", 1, av,
710                         member_list_build, call_args))
711         {
712           moira_disconnect();
713           com_err(whoami, 0, "Couldn't populate list %s : %s", 
714                   after[L_NAME], error_message(rc));
715           return;
716         }
717       if (member_base != NULL)
718         {
719           ptr = member_base;
720           while (ptr != NULL)
721             {
722               if (!strcasecmp(ptr->type, "LIST"))
723                 {
724                   ptr = ptr->next;
725                   continue;
726                 }
727               pUserOu = user_ou;
728               if (!strcasecmp(ptr->type, "STRING"))
729                 {
730                   if (contact_create(ldap_handle, dn_path, ptr->member, contact_ou))
731                     return;
732                   pUserOu = contact_ou;
733                 }
734               else if (!strcasecmp(ptr->type, "KERBEROS"))
735                 {
736                   if (contact_create(ldap_handle, dn_path, ptr->member, kerberos_ou))
737                     return;
738                   pUserOu = kerberos_ou;
739                 }
740               rc = member_add(ldap_handle, dn_path, after[L_NAME],
741                               group_ou, group_membership, ptr->member, pUserOu);
742               ptr = ptr->next;
743             }
744           linklist_free(member_base);
745           member_base = NULL;
746         }
747       moira_disconnect();
748     }
749
750   return;
751 }
752
753 #define LM_EXTRA_ACTIVE   (LM_END)
754 #define LM_EXTRA_PUBLIC   (LM_END+1)
755 #define LM_EXTRA_HIDDEN   (LM_END+2)
756 #define LM_EXTRA_MAILLIST (LM_END+3)
757 #define LM_EXTRA_GROUP    (LM_END+4)
758 #define LM_EXTRA_GID      (LM_END+5)
759 #define LM_EXTRA_END      (LM_END+6)
760
761 void do_member(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
762                char **before, int beforec, char **after, int afterc)
763 {
764   char  group_name[128];
765   char  user_name[128];
766   char  user_type[128];
767   int   rc;
768   char  group_membership[1];
769   int   security_flag;
770   char  group_ou[256];
771   char  *args[16];
772   char  **ptr;
773   char  *pUserOu;
774
775   pUserOu = NULL;
776   ptr = NULL;
777   if (afterc)
778     {
779       if (afterc < LM_EXTRA_END)
780         return;
781       if (!atoi(after[LM_EXTRA_ACTIVE]))
782         return;
783       ptr = after;
784       strcpy(user_name, after[LM_MEMBER]);
785       strcpy(group_name, after[LM_LIST]);
786       strcpy(user_type, after[LM_TYPE]);
787
788     }
789   else if (beforec)
790     {
791       if (beforec < LM_EXTRA_END)
792         return;
793       if (!atoi(before[LM_EXTRA_ACTIVE]))
794           return;
795       ptr = before;
796       strcpy(user_name, before[LM_MEMBER]);
797       strcpy(group_name, before[LM_LIST]);
798       strcpy(user_type, before[LM_TYPE]);
799     }
800
801   if (ptr == NULL)
802     return;
803
804   args[L_NAME] = ptr[LM_LIST];
805   args[L_ACTIVE] = ptr[LM_EXTRA_ACTIVE];
806   args[L_PUBLIC] = ptr[LM_EXTRA_PUBLIC];
807   args[L_HIDDEN] = ptr[LM_EXTRA_HIDDEN];
808   args[L_MAILLIST] = ptr[LM_EXTRA_MAILLIST];
809   args[L_GROUP] = ptr[LM_EXTRA_GROUP];
810   args[L_GID] = ptr[LM_EXTRA_GID];
811
812   security_flag = 0;
813   memset(group_ou, '\0', sizeof(group_ou));
814   get_group_membership(group_membership, group_ou, &security_flag, args);
815   if (strlen(group_ou) == 0)
816     {
817       com_err(whoami, 0, "couldn't find the group OU for group %s", group_name);
818       return;
819     }
820
821   rc = 0;
822   if (beforec)
823     {
824       if (!strcasecmp(ptr[LM_TYPE], "LIST"))
825         return;
826
827       com_err(whoami, 0, "Removing user %s from list %s", user_name, group_name);
828       pUserOu = user_ou;
829       if (!strcasecmp(ptr[LM_TYPE], "STRING"))
830         {
831           if (contact_create(ldap_handle, dn_path, ptr[LM_MEMBER], contact_ou))
832             return;
833           pUserOu = contact_ou;
834         }
835       else if (!strcasecmp(ptr[LM_TYPE], "KERBEROS"))
836         {
837           if (contact_create(ldap_handle, dn_path, ptr[LM_MEMBER], kerberos_ou))
838             return;
839           pUserOu = kerberos_ou;
840         }
841       rc = member_remove(ldap_handle, dn_path, group_name,
842                        group_ou, group_membership, ptr[LM_MEMBER], pUserOu);
843     }
844   else
845     {
846       if (!strcasecmp(ptr[LM_TYPE], "LIST"))
847         return;
848
849       com_err(whoami, 0, "Adding user %s to list %s", user_name, group_name);
850       pUserOu = user_ou;
851       if (!strcasecmp(ptr[LM_TYPE], "STRING"))
852         {
853           if (contact_create(ldap_handle, dn_path, ptr[LM_MEMBER], contact_ou))
854             return;
855           pUserOu = contact_ou;
856         }
857       else if (!strcasecmp(ptr[LM_TYPE], "KERBEROS"))
858         {
859           if (contact_create(ldap_handle, dn_path, ptr[LM_MEMBER], kerberos_ou))
860             return;
861           pUserOu = kerberos_ou;
862         }
863       rc = member_add(ldap_handle, dn_path, group_name,
864                       group_ou, group_membership, ptr[LM_MEMBER], pUserOu);
865     }
866   if (rc)
867     {
868       if (afterc)
869         com_err(whoami, 0, "Couldn't add %s to group %s", user_name, group_name);
870       else
871         com_err(whoami, 0, "Couldn't remove %s to group %s", user_name, group_name);
872     }
873   return;
874 }
875
876
877 void do_user(LDAP *ldap_handle, char *dn_path, char *ldap_hostname, 
878              char **before, int beforec, char **after, 
879              int afterc)
880 {
881   int   rc;
882   char  *av[2];
883   char  *call_args[6];
884   int   astate;
885   int   bstate;
886
887   if ((beforec == 0) && (afterc == 0))
888     return;
889
890   astate = 0;
891   bstate = 0;
892   if (afterc > U_STATE)
893     astate = atoi(after[U_STATE]);
894   if (beforec > U_STATE)
895     bstate = atoi(before[U_STATE]);
896
897   if (astate == 2)
898     astate = 1;
899   if (bstate == 2)
900     bstate = 1;
901
902   if ((bstate == 0) && (astate == 0))
903     return;
904
905   if (astate == bstate)
906     {
907       if (!strcmp(before[U_NAME], after[U_NAME]))
908         {
909           com_err(whoami, 0, "Updating user %s info", before[U_NAME]);
910           rc = user_update(ldap_handle, dn_path, before[U_NAME],
911                            before[U_UID], before[U_MITID]);
912           return;
913         }
914       else
915         {
916           com_err(whoami, 0, "Changing user %s to %s", before[U_NAME],
917                   after[U_NAME]);
918           if ((rc = user_rename(ldap_handle, dn_path, before[U_NAME], 
919                 after[U_NAME], after[U_UID], after[U_MITID], 
920                 atoi(after[U_STATE]))) != LDAP_NO_SUCH_OBJECT)
921             {
922               if (rc != LDAP_SUCCESS)
923                 {
924                   com_err(whoami, 0, "Could not change user %s to %s : %s",
925                           before[U_NAME], 
926                           after[U_NAME], error_message(rc));
927                 }
928               return;
929             }
930         }
931       bstate = 0;
932     }
933
934   if (bstate == 1)
935     {
936       com_err(whoami, 0, "Deactivate user %s in the AD", before[U_NAME]);
937
938       if ((rc = user_change_status(ldap_handle, dn_path, before[U_NAME], 
939                                    MEMBER_DEACTIVATE)) != LDAP_SUCCESS)
940         {
941           com_err(whoami, 0, "Couldn't deactivate user %s in the AD", before[U_NAME]);
942         }
943       return;
944     }
945
946   if (astate == 1)
947     {
948       if (rc = moira_connect())
949         {
950           critical_alert("AD incremental", 
951                          "Error connection to Moira : %s",
952                          error_message(rc));
953           return;
954         }
955       com_err(whoami, 0, "Creating/Reactivating user %s", after[U_NAME]);
956
957       av[0] = after[U_NAME];
958       call_args[0] = (char *)ldap_handle;
959       call_args[1] = dn_path;
960       call_args[2] = (char *)MEMBER_ACTIVATE;
961       call_args[3] = NULL;
962       sid_base = NULL;
963       sid_ptr = &sid_base;
964       UserReactivate = 0;
965       callback_rc = 0;
966       if (rc = mr_query("get_user_account_by_login", 1, av, user_create,
967                         call_args))
968         {
969           moira_disconnect();
970           com_err(whoami, 0, "Couldn't create/activate user %s : %s",
971                   after[U_NAME], error_message(rc));
972           return;
973         }
974       if (callback_rc)
975         {
976           moira_disconnect();
977           com_err(whoami, 0, "Couldn't create/activate user %s", after[U_NAME]);
978           return;
979         }
980       sleep(1);
981       if (sid_base != NULL)
982         {
983           sid_update(ldap_handle, dn_path);
984           linklist_free(sid_base);
985         }
986       if (UserReactivate)
987         {
988           av[0] = "ruser";
989           av[1] = after[U_NAME];
990           call_args[0] = (char *)ldap_handle;
991           call_args[1] = dn_path;
992           call_args[2] = after[U_NAME];
993           call_args[3] = user_ou;
994           rc = mr_query("get_lists_of_member", 2, av, process_lists,
995                           call_args);
996           if (rc && rc != MR_NO_MATCH)
997             {
998               com_err(whoami, 0, "Couldn't retrieve membership of user %s: %s",
999                       after[U_NAME], error_message(rc));
1000             }
1001         }
1002       moira_disconnect();
1003     }
1004
1005   return;
1006 }
1007
1008 int construct_newvalues(LK_ENTRY *linklist_base, int modvalue_count, 
1009                         char *oldValue, char *newValue,
1010                         char ***modvalues, int type)
1011 {
1012   LK_ENTRY    *linklist_ptr;
1013   int         i;
1014   char        *cPtr;
1015
1016   if (((*modvalues) = calloc(1, (modvalue_count + 1) * sizeof(char *)))
1017       == NULL)
1018     {
1019       return(1);
1020     }
1021   for (i = 0; i < (modvalue_count + 1); i++)
1022     (*modvalues)[i] = NULL;
1023   if (modvalue_count != 0)
1024     {
1025       linklist_ptr = linklist_base;
1026       for (i = 0; i < modvalue_count; i++)
1027         {
1028           if ((oldValue != NULL) && (newValue != NULL))
1029             {
1030               if ((cPtr = (char *)strstr(linklist_ptr->value, oldValue))
1031                  != (char *)NULL)
1032                 {
1033                   if (type == REPLACE)
1034                     {
1035                       if (((*modvalues)[i] = calloc(1, strlen(newValue) + 1))
1036                           == NULL)
1037                         return(1);
1038                       memset((*modvalues)[i], '\0', strlen(newValue) + 1);
1039                       strcpy((*modvalues)[i], newValue);
1040                     }
1041                   else
1042                     {
1043                       if (((*modvalues)[i] = calloc(1, 
1044                                         (int)(cPtr - linklist_ptr->value) + 
1045                                         (linklist_ptr->length - strlen(oldValue)) + 
1046                                         strlen(newValue) + 1)) == NULL)
1047                         return(1);
1048                       memset((*modvalues)[i], '\0', 
1049                              (int)(cPtr - linklist_ptr->value) + 
1050                              (linklist_ptr->length - strlen(oldValue)) + 
1051                              strlen(newValue) + 1);
1052                       memcpy((*modvalues)[i], linklist_ptr->value, 
1053                              (int)(cPtr - linklist_ptr->value));
1054                       strcat((*modvalues)[i], newValue);
1055                       strcat((*modvalues)[i], 
1056      &linklist_ptr->value[(int)(cPtr - linklist_ptr->value) + strlen(oldValue)]);
1057                     }
1058                 }
1059               else
1060                 {
1061                   (*modvalues)[i] = calloc(1, linklist_ptr->length + 1);
1062                   memset((*modvalues)[i], '\0', linklist_ptr->length + 1);
1063                   memcpy((*modvalues)[i], linklist_ptr->value,
1064                          linklist_ptr->length);
1065                 }
1066             }
1067         else
1068             {
1069               (*modvalues)[i] = calloc(1, linklist_ptr->length + 1);
1070               memset((*modvalues)[i], '\0', linklist_ptr->length + 1);
1071               memcpy((*modvalues)[i], linklist_ptr->value,
1072                      linklist_ptr->length);
1073             }
1074           linklist_ptr = linklist_ptr->next;
1075         }
1076       (*modvalues)[i] = NULL;
1077     }
1078   return(0);
1079 }
1080
1081
1082 int linklist_build(LDAP *ldap_handle, char *dn_path, char *search_exp, 
1083                    char **attr_array, LK_ENTRY **linklist_base,
1084                    int *linklist_count)
1085 {
1086   ULONG       rc;
1087   LDAPMessage *ldap_entry;
1088
1089   rc = 0;
1090   ldap_entry = NULL;
1091   (*linklist_base) = NULL;
1092   (*linklist_count) = 0;
1093   if ((rc = ldap_search_s(ldap_handle, dn_path, LDAP_SCOPE_SUBTREE, 
1094                           search_exp, attr_array, 0, &ldap_entry))
1095       != LDAP_SUCCESS)
1096     return(0);
1097   rc = retrieve_entries(ldap_handle, ldap_entry, linklist_base, linklist_count);
1098
1099   ldap_msgfree(ldap_entry);
1100   return(rc);
1101 }
1102
1103
1104 int retrieve_entries(LDAP *ldap_handle, LDAPMessage *ldap_entry, 
1105                      LK_ENTRY **linklist_base, int *linklist_count)
1106 {
1107   char        distinguished_name[1024];
1108   LK_ENTRY    *linklist_ptr;
1109   int         rc;
1110
1111   if ((ldap_entry = ldap_first_entry(ldap_handle, ldap_entry)) == NULL)
1112     return(0);
1113
1114   memset(distinguished_name, '\0', sizeof(distinguished_name));
1115   get_distinguished_name(ldap_handle, ldap_entry, distinguished_name);
1116
1117   if ((rc = retrieve_attributes(ldap_handle, ldap_entry, distinguished_name,
1118                                 linklist_base)) != 0)
1119     return(rc);
1120
1121   while ((ldap_entry = ldap_next_entry(ldap_handle, ldap_entry)) != NULL)
1122     {
1123       memset(distinguished_name, '\0', sizeof(distinguished_name));
1124       get_distinguished_name(ldap_handle, ldap_entry, distinguished_name);
1125
1126       if ((rc = retrieve_attributes(ldap_handle, ldap_entry, distinguished_name,
1127                                     linklist_base)) != 0)
1128         return(rc);
1129     }
1130
1131   linklist_ptr = (*linklist_base);
1132   (*linklist_count) = 0;
1133   while (linklist_ptr != NULL)
1134     {
1135       ++(*linklist_count);
1136       linklist_ptr = linklist_ptr->next;
1137     }
1138   return(0);
1139 }
1140
1141 int retrieve_attributes(LDAP *ldap_handle, LDAPMessage *ldap_entry, 
1142                         char *distinguished_name, LK_ENTRY **linklist_current)
1143 {
1144   char        *Attribute;
1145   BerElement  *ptr;
1146
1147   ptr = NULL;
1148   if ((Attribute = ldap_first_attribute(ldap_handle, ldap_entry, &ptr)) != NULL)
1149     {
1150       retrieve_values(ldap_handle, ldap_entry, Attribute, distinguished_name,
1151                       linklist_current);
1152       ldap_memfree(Attribute);
1153       while ((Attribute = ldap_next_attribute(ldap_handle, ldap_entry, 
1154                                               ptr)) != NULL)
1155         {
1156           retrieve_values(ldap_handle, ldap_entry, Attribute,
1157                           distinguished_name, linklist_current);
1158           ldap_memfree(Attribute);
1159         }
1160     }
1161   ldap_ber_free(ptr, 0);
1162   return(0);
1163 }
1164
1165 int retrieve_values(LDAP *ldap_handle, LDAPMessage *ldap_entry,
1166                     char *Attribute, char *distinguished_name,
1167                     LK_ENTRY **linklist_current)
1168 {
1169   char        **str_value;
1170   char        temp[256];
1171   void        **Ptr;
1172   int         use_bervalue;
1173   LK_ENTRY    *linklist_previous;
1174   LDAP_BERVAL **ber_value;
1175   DWORD       ber_length;
1176 #ifdef LDAP_DEBUG
1177   SID         *sid;
1178   GUID        *guid;
1179   int         i;
1180   int         intValue;
1181   DWORD       *subauth;
1182   SID_IDENTIFIER_AUTHORITY    *sid_auth;
1183   unsigned char   *subauth_count;
1184 #endif /*LDAP_BEGUG*/
1185
1186   use_bervalue = 0;
1187   memset(temp, '\0', sizeof(temp));
1188   if ((!strcmp(Attribute, "objectSid")) ||
1189       (!strcmp(Attribute, "objectGUID")))
1190     use_bervalue = 1;
1191
1192   if (use_bervalue)
1193     {
1194       ber_value = ldap_get_values_len(ldap_handle, ldap_entry, Attribute);
1195       Ptr = (void **)ber_value;
1196       str_value = NULL;
1197       }
1198   else
1199     {
1200       str_value = ldap_get_values(ldap_handle, ldap_entry, Attribute);
1201       Ptr = (void **)str_value;
1202       ber_value = NULL;
1203     }
1204   if (Ptr != NULL)
1205     {
1206       for (; *Ptr; Ptr++) 
1207         {
1208           if ((linklist_previous = calloc(1, sizeof(LK_ENTRY))) == NULL)
1209             return(1);
1210           memset(linklist_previous, '\0', sizeof(LK_ENTRY));
1211           linklist_previous->next = (*linklist_current);
1212           (*linklist_current) = linklist_previous;
1213
1214           if (((*linklist_current)->attribute = calloc(1, 
1215                                                strlen(Attribute) + 1)) == NULL)
1216             return(1);
1217           memset((*linklist_current)->attribute, '\0', strlen(Attribute) + 1);
1218           strcpy((*linklist_current)->attribute, Attribute);
1219           if (use_bervalue)
1220             {
1221               ber_length = (*(LDAP_BERVAL **)Ptr)->bv_len;
1222               if (((*linklist_current)->value = calloc(1, ber_length)) == NULL)
1223                 return(1);
1224               memset((*linklist_current)->value, '\0', ber_length);
1225               memcpy((*linklist_current)->value, (*(LDAP_BERVAL **)Ptr)->bv_val, 
1226                                                   ber_length);
1227               (*linklist_current)->length = ber_length;
1228             }
1229           else
1230             {
1231               if (((*linklist_current)->value = calloc(1, 
1232                                                   strlen(*Ptr) + 1)) == NULL)
1233                 return(1);
1234               memset((*linklist_current)->value, '\0', strlen(*Ptr) + 1);
1235               (*linklist_current)->length = strlen(*Ptr);
1236               strcpy((*linklist_current)->value, *Ptr);
1237             }
1238           (*linklist_current)->ber_value = use_bervalue;
1239           if (((*linklist_current)->dn = calloc(1, 
1240                                       strlen(distinguished_name) + 1)) == NULL)
1241             return(1);
1242           memset((*linklist_current)->dn, '\0', strlen(distinguished_name) + 1);
1243           strcpy((*linklist_current)->dn, distinguished_name);
1244
1245 #ifdef LDAP_DEBUG
1246           if (!strcmp(Attribute, "objectGUID"))
1247             {
1248               guid = (GUID *)((*linklist_current)->value);
1249               sprintf(temp, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", 
1250                       guid->Data1, guid->Data2, guid->Data3, 
1251                       guid->Data4[0], guid->Data4[1], guid->Data4[2], 
1252                       guid->Data4[3], guid->Data4[4], guid->Data4[5], 
1253                       guid->Data4[6], guid->Data4[7]);
1254               print_to_screen("     %20s : {%s}\n", Attribute, temp);
1255             }
1256           else if (!strcmp(Attribute, "objectSid"))
1257             {
1258               sid = (SID *)((*(LDAP_BERVAL **)Ptr)->bv_val);
1259 #ifdef _WIN32
1260               print_to_screen("        Revision = %d\n", sid->Revision);
1261               print_to_screen("        SID Identifier Authority:\n");
1262               sid_auth = &sid->IdentifierAuthority;
1263               if (sid_auth->Value[0])
1264                 print_to_screen("            SECURITY_NULL_SID_AUTHORITY\n");
1265               else if (sid_auth->Value[1])
1266                 print_to_screen("            SECURITY_WORLD_SID_AUTHORITY\n");
1267               else if (sid_auth->Value[2])
1268                 print_to_screen("            SECURITY_LOCAL_SID_AUTHORITY\n");
1269               else if (sid_auth->Value[3])
1270                 print_to_screen("            SECURITY_CREATOR_SID_AUTHORITY\n");
1271               else if (sid_auth->Value[5])
1272                 print_to_screen("            SECURITY_NT_AUTHORITY\n");
1273               else
1274                 print_to_screen("            UNKNOWN SID AUTHORITY\n");
1275               subauth_count = GetSidSubAuthorityCount(sid);
1276               print_to_screen("        SidSubAuthorityCount = %d\n", 
1277                               *subauth_count);
1278               print_to_screen("        SidSubAuthority:\n");
1279               for (i = 0; i < *subauth_count; i++)
1280                 {
1281                   if ((subauth = GetSidSubAuthority(sid, i)) != NULL)
1282                     print_to_screen("            %u\n", *subauth);
1283                 }
1284 #endif
1285             }
1286           else if ((!memcmp(Attribute, "userAccountControl", 
1287                             strlen("userAccountControl"))) ||
1288                    (!memcmp(Attribute, "sAMAccountType", 
1289                             strlen("sAmAccountType"))))
1290             {
1291               intValue = atoi(*Ptr);
1292               print_to_screen("     %20s : %ld\n",Attribute, intValue);
1293               if (!memcmp(Attribute, "userAccountControl", 
1294                           strlen("userAccountControl")))
1295                 {
1296                   if (intValue & UF_ACCOUNTDISABLE)
1297                     print_to_screen("     %20s :    %s\n", 
1298                                     "", "Account disabled");
1299                   else
1300                     print_to_screen("     %20s :    %s\n", 
1301                                     "", "Account active");
1302                   if (intValue & UF_HOMEDIR_REQUIRED)
1303                     print_to_screen("     %20s :    %s\n", 
1304                                     "", "Home directory required");
1305                   if (intValue & UF_LOCKOUT)
1306                     print_to_screen("     %20s :    %s\n", 
1307                                     "", "Account locked out");
1308                   if (intValue & UF_PASSWD_NOTREQD)
1309                     print_to_screen("     %20s :    %s\n", 
1310                                     "", "No password required");
1311                   if (intValue & UF_PASSWD_CANT_CHANGE)
1312                     print_to_screen("     %20s :    %s\n",
1313                                     "", "Cannot change password");
1314                   if (intValue & UF_TEMP_DUPLICATE_ACCOUNT)
1315                     print_to_screen("     %20s :    %s\n", 
1316                                     "", "Temp duplicate account");
1317                   if (intValue & UF_NORMAL_ACCOUNT)
1318                     print_to_screen("     %20s :    %s\n", 
1319                                     "", "Normal account");
1320                   if (intValue & UF_INTERDOMAIN_TRUST_ACCOUNT)
1321                     print_to_screen("     %20s :    %s\n", 
1322                                     "", "Interdomain trust account");
1323                   if (intValue & UF_WORKSTATION_TRUST_ACCOUNT)
1324                     print_to_screen("     %20s :    %s\n", 
1325                                     "", "Workstation trust account");
1326                   if (intValue & UF_SERVER_TRUST_ACCOUNT)
1327                     print_to_screen("     %20s :    %s\n", 
1328                                     "", "Server trust account");
1329                 }
1330             }
1331           else
1332             {
1333               print_to_screen("     %20s : %s\n",Attribute, *Ptr);
1334             }
1335 #endif /*LDAP_DEBUG*/
1336         }
1337       if (str_value != NULL)
1338         ldap_value_free(str_value);
1339       if (ber_value != NULL)
1340         ldap_value_free_len(ber_value);
1341     }
1342   (*linklist_current) = linklist_previous;
1343   return(0);
1344 }
1345
1346 int moira_connect(void)
1347 {
1348   long    rc;
1349   char    HostName[64];
1350
1351   if (!mr_connections++)
1352     {
1353 #ifdef _WIN32
1354       memset(HostName, '\0', sizeof(HostName));
1355       strcpy(HostName, "ttsp");
1356       rc = mr_connect_cl(HostName, "winad.incr", QUERY_VERSION, 1);
1357 /*det
1358       rc = mr_connect(HostName);
1359 */
1360 #else
1361       struct utsname uts;
1362       uname(&uts);
1363       rc = mr_connect_cl(uts.nodename, "winad.incr", QUERY_VERSION, 1);
1364 /*
1365       rc = mr_connect(uts.nodename);
1366 */
1367 #endif /*WIN32*/
1368 /*det
1369       if (!rc)
1370         rc = mr_auth("winad.incr");
1371 */
1372       return rc;
1373     }
1374   return 0;
1375 }
1376
1377 void check_winad(void)
1378 {
1379   int i;
1380   
1381   for (i = 0; file_exists(STOP_FILE); i++)
1382     {
1383       if (i > 30)
1384         {
1385           critical_alert("AD incremental",
1386                          "WINAD incremental failed (%s exists): %s",
1387                          STOP_FILE, tbl_buf);
1388           exit(1);
1389         }
1390       sleep(60);
1391     }
1392 }
1393
1394 int moira_disconnect(void)
1395 {
1396
1397   if (!--mr_connections)
1398     {
1399       mr_disconnect();
1400     }
1401   return 0;
1402 }
1403
1404 void get_distinguished_name(LDAP *ldap_handle, LDAPMessage *ldap_entry, 
1405                             char *distinguished_name)
1406 {
1407   char    *CName;
1408
1409   CName = ldap_get_dn(ldap_handle, ldap_entry);
1410   if (CName == NULL)
1411     return;
1412   strcpy(distinguished_name, CName);
1413   ldap_memfree(CName);
1414 }
1415
1416 int linklist_create_entry(char *attribute, char *value, 
1417                           LK_ENTRY **linklist_entry)
1418 {
1419   (*linklist_entry) = calloc(1, sizeof(LK_ENTRY));
1420   if (!(*linklist_entry))
1421     {
1422       return(1);
1423     }
1424   memset((*linklist_entry), '\0', sizeof(LK_ENTRY));
1425   (*linklist_entry)->attribute = calloc(1, strlen(attribute) + 1);
1426   memset((*linklist_entry)->attribute, '\0', strlen(attribute) + 1);
1427   strcpy((*linklist_entry)->attribute, attribute);
1428   (*linklist_entry)->value = calloc(1, strlen(value) + 1);
1429   memset((*linklist_entry)->value, '\0', strlen(value) + 1);
1430   strcpy((*linklist_entry)->value, value);
1431   (*linklist_entry)->length = strlen(value);
1432   (*linklist_entry)->next = NULL;
1433   return(0);
1434 }
1435
1436 void print_to_screen(const char *fmt, ...)
1437 {
1438   va_list pvar;
1439
1440   va_start(pvar, fmt);
1441   vfprintf(stderr, fmt, pvar);
1442   fflush(stderr);
1443   va_end(pvar);
1444 }
1445
1446 int get_group_membership(char *group_membership, char *group_ou, 
1447                          int *security_flag, char **av)
1448 {
1449   int  maillist_flag;
1450   int  group_flag;
1451
1452   maillist_flag = atoi(av[L_MAILLIST]);
1453   group_flag = atoi(av[L_GROUP]);
1454   if (security_flag != NULL)
1455     (*security_flag) = 0;
1456
1457   if ((maillist_flag) && (group_flag))
1458     {
1459       if (group_membership != NULL)
1460         group_membership[0] = 'B';
1461       if (security_flag != NULL)
1462         (*security_flag) = 1;
1463       if (group_ou != NULL)
1464         strcpy(group_ou, group_ou_both);
1465     }
1466   else if ((!maillist_flag) && (group_flag))
1467     {
1468       if (group_membership != NULL)
1469         group_membership[0] = 'S';
1470       if (security_flag != NULL)
1471         (*security_flag) = 1;
1472       if (group_ou != NULL)
1473         strcpy(group_ou, group_ou_security);
1474     }
1475   else if ((maillist_flag) && (!group_flag))
1476     {
1477       if (group_membership != NULL)
1478         group_membership[0] = 'D';
1479       if (group_ou != NULL)
1480         strcpy(group_ou, group_ou_distribution);
1481     }
1482   else
1483     {
1484       if (group_membership != NULL)
1485         group_membership[0] = 'N';
1486       if (group_ou != NULL)
1487         strcpy(group_ou, group_ou_neither);
1488     }
1489   return(0);
1490 }
1491
1492 int group_rename(LDAP *ldap_handle, char *dn_path, 
1493                  char *before_group_name, char *before_group_membership, 
1494                  char *before_group_ou, int before_security_flag, char *before_desc,
1495                  char *after_group_name, char *after_group_membership, 
1496                  char *after_group_ou, int after_security_flag, char *after_desc)
1497 {
1498   LDAPMod   *mods[20];
1499   char      old_dn[512];
1500   char      new_dn[512];
1501   char      new_dn_path[512];
1502   char      sam_name[256];
1503   char      filter_exp[4096];
1504   char      *attr_array[3];
1505   char      *name_v[] = {NULL, NULL};
1506   char      *desc_v[] = {NULL, NULL};
1507   char      *samAccountName_v[] = {NULL, NULL};
1508   int       n;
1509   int       i;
1510   int       rc;
1511   LK_ENTRY  *group_base;
1512   int       group_count;
1513
1514   if (!check_string(before_group_name))
1515     {
1516       com_err(whoami, 0, "invalid LDAP list name %s", before_group_name);
1517       return(-1);
1518     }
1519   if (!check_string(after_group_name))
1520     {
1521       com_err(whoami, 0, "invalid LDAP list name %s", after_group_name);
1522       return(-1);
1523     }
1524
1525   sprintf(filter_exp, "(sAMAccountName=%s_zZx%c)", before_group_name, before_group_membership[0]);
1526   attr_array[0] = "distinguishedName";
1527   attr_array[1] = NULL;
1528   if ((rc = linklist_build(ldap_handle, dn_path, filter_exp, attr_array, 
1529                            &group_base, &group_count)) != 0)
1530     {
1531       com_err(whoami, 0, "LDAP server unable to get list %s dn : %s",
1532               after_group_name, ldap_err2string(rc));
1533       return(rc);
1534     }
1535   if (group_count != 1)
1536     {
1537       com_err(whoami, 0, "LDAP server unable to find list %s in AD",
1538               after_group_name);
1539       callback_rc = LDAP_NO_SUCH_OBJECT;
1540       return(-1);
1541     }
1542   strcpy(old_dn, group_base->value);
1543   linklist_free(group_base);
1544   group_base = NULL;
1545   group_count = 0;
1546
1547   sprintf(new_dn_path, "%s,%s", after_group_ou, dn_path);
1548   sprintf(new_dn, "cn=%s", after_group_name);
1549   if ((rc = ldap_rename_s(ldap_handle, old_dn, new_dn, new_dn_path,
1550                           TRUE, NULL, NULL)) != LDAP_SUCCESS)
1551     {
1552       com_err(whoami, 0, "Couldn't rename list from %s to %s : %s",
1553               after_group_name, after_group_name, ldap_err2string(rc));
1554       return(rc);
1555     }
1556
1557   sprintf(sam_name, "%s_zZx%c", after_group_name, after_group_membership[0]);
1558   name_v[0] = after_group_name;
1559   samAccountName_v[0] = sam_name;
1560   desc_v[0] = after_desc;
1561   n = 0;
1562   ADD_ATTR("samAccountName", samAccountName_v, LDAP_MOD_REPLACE);
1563   ADD_ATTR("displayName", name_v, LDAP_MOD_REPLACE);
1564   if (strlen(after_desc) == 0)
1565     desc_v[0] = NULL;
1566   ADD_ATTR("description", desc_v, LDAP_MOD_REPLACE);
1567   mods[n] = NULL;
1568   sprintf(new_dn, "cn=%s,%s,%s", after_group_name, after_group_ou, dn_path);
1569   if ((rc = ldap_modify_s(ldap_handle, new_dn, mods)) != LDAP_SUCCESS)
1570     {
1571       com_err(whoami, 0, "After renaming, couldn't modify list data for %s : %s",
1572               after_group_name, ldap_err2string(rc));
1573     }
1574   for (i = 0; i < n; i++)
1575     free(mods[i]);
1576   return(rc);
1577 }
1578
1579 int group_create(int ac, char **av, void *ptr)
1580 {
1581   LDAPMod *mods[20];
1582   LK_ENTRY  *group_base;
1583   char new_dn[256];
1584   char group_ou[256];
1585   char new_group_name[256];
1586   char sam_group_name[256];
1587   char cn_group_name[256];
1588   char *cn_v[] = {NULL, NULL};
1589   char *objectClass_v[] = {"top", "group", NULL};
1590   char info[256];
1591   char *samAccountName_v[] = {NULL, NULL};
1592   char *managedBy_v[] = {NULL, NULL};
1593   char *altSecurityIdentities_v[] = {NULL, NULL};
1594   char *name_v[] = {NULL, NULL};
1595   char *desc_v[] = {NULL, NULL};
1596   char *info_v[] = {NULL, NULL};
1597   char *groupTypeControl_v[] = {NULL, NULL};
1598   char groupTypeControlStr[80];
1599   char group_membership[1];
1600   int  i;
1601   int  security_flag;
1602   u_int groupTypeControl = ADS_GROUP_TYPE_GLOBAL_GROUP;
1603   int  n;
1604   int  rc;
1605   int  group_count;
1606   char filter_exp[256];
1607   char *attr_array[3];
1608   char **call_args;
1609
1610   call_args = ptr;
1611
1612   if (!atoi(av[L_ACTIVE]))
1613     return(1);
1614   if (!check_string(av[L_NAME]))
1615     {
1616       com_err(whoami, 0, "invalid LDAP list name %s", av[L_NAME]);
1617       return(1);
1618     }
1619
1620   memset(group_ou, 0, sizeof(group_ou));
1621   memset(group_membership, 0, sizeof(group_membership));
1622   security_flag = 0;
1623   get_group_membership(group_membership, group_ou, &security_flag, av);
1624
1625   if (security_flag)
1626     groupTypeControl |= ADS_GROUP_TYPE_SECURITY_ENABLED;
1627   sprintf(groupTypeControlStr, "%ld", groupTypeControl);
1628   groupTypeControl_v[0] = groupTypeControlStr;
1629
1630   strcpy(new_group_name, av[L_NAME]);
1631   strcpy(cn_group_name, av[L_NAME]);
1632   sprintf(sam_group_name, "%s_zZx%c", av[L_NAME], group_membership[0]);
1633
1634   samAccountName_v[0] = sam_group_name;
1635   name_v[0] = new_group_name;
1636   cn_v[0] = new_group_name;
1637
1638   sprintf(new_dn, "cn=%s,%s,%s", new_group_name, group_ou, call_args[1]);
1639   n = 0;
1640   ADD_ATTR("cn", cn_v, LDAP_MOD_ADD);
1641   ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
1642   ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_ADD);
1643   ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
1644   ADD_ATTR("name", name_v, LDAP_MOD_ADD);
1645   if (strlen(av[L_DESC]) != 0)
1646     {
1647       desc_v[0] = av[L_DESC];
1648       ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
1649     }
1650   ADD_ATTR("groupType", groupTypeControl_v, LDAP_MOD_ADD);
1651   if (strlen(av[L_ACE_NAME]) != 0)
1652     {
1653       sprintf(info, "The Administrator of this list is the LIST: %s", av[L_ACE_NAME]);
1654       info_v[0] = info;
1655       ADD_ATTR("info", info_v, LDAP_MOD_ADD);
1656     }
1657   mods[n] = NULL;
1658
1659   rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL);
1660
1661   for (i = 0; i < n; i++)
1662     free(mods[i]);
1663   if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
1664     {
1665       com_err(whoami, 0, "Unable to create list %s in AD : %s",
1666               av[L_NAME], ldap_err2string(rc));
1667       callback_rc = rc;
1668       return(rc);
1669     }
1670   if (rc == LDAP_ALREADY_EXISTS)
1671     {
1672       n = 0;
1673       desc_v[0] = av[L_DESC];
1674       if (strlen(av[L_DESC]) == 0)
1675         desc_v[0] = NULL;
1676       ADD_ATTR("description", desc_v, LDAP_MOD_REPLACE);
1677       mods[n] = NULL;
1678       rc = ldap_modify_s((LDAP *)call_args[0], new_dn, mods);
1679       for (i = 0; i < n; i++)
1680         free(mods[i]);
1681     }
1682   sprintf(filter_exp, "(sAMAccountName=%s)", sam_group_name);
1683   attr_array[0] = "objectSid";
1684   attr_array[1] = NULL;
1685   group_count = 0;
1686   group_base = NULL;
1687   if ((rc = linklist_build((LDAP *)call_args[0], call_args[1], filter_exp, attr_array, 
1688                            &group_base, &group_count)) == LDAP_SUCCESS)
1689     {
1690       if (group_count == 1)
1691         {
1692           (*sid_ptr) = group_base;
1693           (*sid_ptr)->member = strdup(av[L_NAME]);
1694           (*sid_ptr)->type = (char *)GROUPS;
1695           sid_ptr = &(*sid_ptr)->next;
1696         }
1697       else
1698         {
1699           if (group_base != NULL)
1700             linklist_free(group_base);
1701         }
1702     }
1703   else
1704     {
1705       if (group_base != NULL)
1706         linklist_free(group_base);
1707     }
1708   return(LDAP_SUCCESS);
1709 }
1710
1711 int group_delete(LDAP *ldap_handle, char *dn_path, char *group_name, char *group_membership)
1712 {
1713   LK_ENTRY  *group_base;
1714   char      *attr_array[3];
1715   char      filter_exp[1024];
1716   char      sam_group_name[256];
1717   char      temp[512];
1718   int       group_count;
1719   int       rc;
1720
1721   if (!check_string(group_name))
1722     {
1723       com_err(whoami, 0, "invalid LDAP list name %s", group_name);
1724       return(-1);
1725     }
1726   rc = 1;
1727   group_count = 0;
1728   group_base = NULL;
1729   attr_array[0] = "distinguishedName";
1730   attr_array[1] = NULL;
1731   strcpy(sam_group_name, group_name);
1732   sprintf(temp, "%s,%s", group_ou_root, dn_path);
1733   sprintf(filter_exp, "(sAMAccountName=%s_zZx%c)", group_name, group_membership[0]);
1734   if (linklist_build(ldap_handle, temp, filter_exp, attr_array, 
1735                            &group_base, &group_count) != 0)
1736     return(-1);
1737   if (group_count == 1)
1738     {
1739       if ((rc = ldap_delete_s(ldap_handle, group_base->value)) != LDAP_SUCCESS)
1740         {
1741           linklist_free(group_base);
1742           com_err(whoami, 0, "Unable to delete list %s from AD : %s",
1743                   group_name, ldap_err2string(rc));
1744           return(-1);
1745         }
1746       linklist_free(group_base);
1747     }
1748   else
1749     {
1750       linklist_free(group_base);
1751       com_err(whoami, 0, "Unable to find list %s in AD.", group_name);
1752       return(-1);
1753     }
1754
1755   return(0);
1756 }
1757
1758 int process_lists(int ac, char **av, void *ptr)
1759 {
1760   int   rc;
1761   int   security_flag;
1762   char  group_ou[256];
1763   char  group_membership[2];
1764   char  **call_args;
1765
1766   call_args = ptr;
1767
1768   security_flag = 0;
1769   memset(group_ou, '\0', sizeof(group_ou));
1770   memset(group_membership, '\0', sizeof(group_membership));
1771   get_group_membership(group_membership, group_ou, &security_flag, av);
1772   rc = member_add((LDAP *)call_args[0], (char *)call_args[1], av[L_NAME],
1773                   group_ou, group_membership, call_args[2],  (char *)call_args[3]);
1774   if (rc)
1775     {
1776       com_err(whoami, 0, "Couldn't add %s to group %s", call_args[2], av[L_NAME]);
1777     }
1778   return(0);
1779 }
1780
1781 int member_list_build(int ac, char **av, void *ptr)
1782 {
1783   LK_ENTRY  *linklist;
1784   char      temp[1024];
1785   char      **call_args;
1786
1787   call_args = ptr;
1788
1789   strcpy(temp, av[ACE_NAME]);
1790   if (!check_string(temp))
1791     return(0);
1792   if (!strcmp(av[ACE_TYPE], "USER"))
1793     {
1794       if (!((int)call_args[3] & MOIRA_USERS))
1795         return(0);
1796     }
1797   else if (!strcmp(av[ACE_TYPE], "STRING"))
1798     {
1799       if (!((int)call_args[3] & MOIRA_STRINGS))
1800         return(0);
1801       if (contact_create((LDAP *)call_args[0], call_args[1], temp, contact_ou))
1802         return(0);
1803     }
1804   else if (!strcmp(av[ACE_TYPE], "LIST"))
1805     {
1806       if (!((int)call_args[3] & MOIRA_LISTS))
1807         return(0);
1808     }
1809   else if (!strcmp(av[ACE_TYPE], "KERBEROS"))
1810     {
1811       if (!((int)call_args[3] & MOIRA_KERBEROS))
1812         return(0);
1813       if (contact_create((LDAP *)call_args[0], call_args[1], temp, kerberos_ou))
1814         return(0);
1815     }
1816   else
1817     return(0);
1818
1819   linklist = member_base;
1820   while (linklist)
1821     {
1822     if (!strcasecmp(temp, linklist->member))
1823       return(0);
1824     linklist = linklist->next;
1825     }
1826   linklist = calloc(1, sizeof(LK_ENTRY));
1827   linklist->op = 1;
1828   linklist->dn = NULL;
1829   linklist->list = calloc(1, strlen(call_args[2]) + 1);
1830   strcpy(linklist->list, call_args[2]);
1831   linklist->type = calloc(1, strlen(av[ACE_TYPE]) + 1);
1832   strcpy(linklist->type, av[ACE_TYPE]);
1833   linklist->member = calloc(1, strlen(temp) + 1);
1834   strcpy(linklist->member, temp);
1835   linklist->next = member_base;
1836   member_base = linklist;
1837   return(0);
1838 }
1839
1840 int member_remove(LDAP *ldap_handle, char *dn_path, char *group_name, 
1841                   char *group_ou, char *group_membership, char *user_name,
1842                   char *UserOu)
1843 {
1844   char        distinguished_name[1024];
1845   char        *modvalues[2];
1846   char        filter_exp[4096];
1847   char        *attr_array[3];
1848   char        temp[256];
1849   int         group_count;
1850   int         i;
1851   int         n;
1852   LDAPMod     *mods[20];
1853   LK_ENTRY    *group_base;
1854   ULONG       rc;
1855
1856   if (!check_string(group_name))
1857     return(1);
1858   strcpy(temp, group_name);
1859   sprintf(filter_exp, "(sAMAccountName=%s_zZx%c)", group_name, group_membership[0]);
1860   attr_array[0] = "distinguishedName";
1861   attr_array[1] = NULL;
1862   if ((rc = linklist_build(ldap_handle, dn_path, filter_exp, attr_array, 
1863                            &group_base, &group_count)) != 0)
1864     {
1865       com_err(whoami, 0, "LDAP server unable to get list %s info : %s",
1866               group_name, ldap_err2string(rc));
1867       goto cleanup;
1868     }
1869   if (group_count != 1)
1870     {
1871       com_err(whoami, 0, "LDAP server unable to find list %s in AD",
1872               group_name);
1873       linklist_free(group_base);
1874       group_base = NULL;
1875       group_count = 0;
1876       goto cleanup;
1877     }
1878   strcpy(distinguished_name, group_base->value);
1879   linklist_free(group_base);
1880   group_base = NULL;
1881   group_count = 0;
1882
1883   sprintf(temp, "CN=%s,%s,%s", user_name, UserOu, dn_path);
1884   modvalues[0] = temp;
1885   modvalues[1] = NULL;
1886
1887   n = 0;
1888   ADD_ATTR("member", modvalues, LDAP_MOD_DELETE);
1889   mods[n] = NULL;
1890   rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
1891   for (i = 0; i < n; i++)
1892     free(mods[i]);
1893   if (rc != LDAP_SUCCESS)
1894     {
1895       com_err(whoami, 0, "LDAP server unable to modify list %s members : %s",
1896               group_name, ldap_err2string(rc));
1897       goto cleanup;
1898     }
1899
1900 cleanup:
1901   return(rc);
1902 }
1903
1904 int member_add(LDAP *ldap_handle, char *dn_path, char *group_name, 
1905                char *group_ou, char *group_membership, char *user_name, char *UserOu)
1906 {
1907   char        distinguished_name[1024];
1908   char        *modvalues[2];
1909   char        filter_exp[4096];
1910   char        *attr_array[3];
1911   char        temp[256];
1912   int         group_count;
1913   int         n;
1914   int         i;
1915   LDAPMod     *mods[20];
1916   LK_ENTRY    *group_base;
1917   ULONG       rc;
1918
1919   rc = 0;
1920   group_base = NULL;
1921   group_count = 0;
1922
1923   if (!check_string(group_name))
1924     return(-1);
1925
1926   strcpy(temp, group_name);
1927   sprintf(filter_exp, "(sAMAccountName=%s_zZx%c)", group_name, group_membership[0]);
1928   attr_array[0] = "distinguishedName";
1929   attr_array[1] = NULL;
1930   if ((rc = linklist_build(ldap_handle, dn_path, filter_exp, attr_array, 
1931                            &group_base, &group_count)) != 0)
1932     {
1933       com_err(whoami, 0, "LDAP server unable to get list %s info : %s",
1934               group_name, ldap_err2string(rc));
1935       return(-1);
1936     }
1937   if (group_count != 1)
1938     {
1939       linklist_free(group_base);
1940       group_base = NULL;
1941       group_count = 0;
1942       com_err(whoami, 0, "LDAP server unable to find list %s in AD",
1943               group_name);
1944       return(-1);
1945     }
1946
1947   strcpy(distinguished_name, group_base->value);
1948   linklist_free(group_base);
1949   group_base = NULL;
1950   group_count = 0;
1951
1952   sprintf(temp, "CN=%s,%s,%s", user_name, UserOu, dn_path);
1953   modvalues[0] = temp;
1954   modvalues[1] = NULL;
1955
1956   n = 0;
1957   ADD_ATTR("member", modvalues, LDAP_MOD_ADD);
1958   mods[n] = NULL;
1959   rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
1960   if (rc == LDAP_ALREADY_EXISTS)
1961     rc = LDAP_SUCCESS;
1962   for (i = 0; i < n; i++)
1963     free(mods[i]);
1964   if (rc != LDAP_SUCCESS)
1965     {
1966       com_err(whoami, 0, "LDAP server unable to modify list %s members in AD : %s",
1967               group_name, ldap_err2string(rc));
1968     }
1969
1970   return(rc);
1971 }
1972
1973 int contact_create(LDAP *ld, char *bind_path, char *user, char *group_ou)
1974 {
1975   LDAPMod *mods[20];
1976   char new_dn[256];
1977   char cn_user_name[256];
1978   char contact_name[256];
1979   char *email_v[] = {NULL, NULL};
1980   char *cn_v[] = {NULL, NULL};
1981   char *contact_v[] = {NULL, NULL};
1982   char *objectClass_v[] = {"top", "person", 
1983                            "organizationalPerson", 
1984                            "contact", NULL};
1985   char *name_v[] = {NULL, NULL};
1986   char *desc_v[] = {NULL, NULL};
1987   int  n;
1988   int  rc;
1989   int  i;
1990
1991   if (!check_string(user))
1992     {
1993       com_err(whoami, 0, "invalid LDAP name %s", user);
1994       return(-1);
1995     }
1996   strcpy(contact_name, user);
1997   sprintf(cn_user_name,"CN=%s,%s,%s", contact_name, group_ou, bind_path);
1998   cn_v[0] = cn_user_name;
1999   contact_v[0] = contact_name;
2000   name_v[0] = user;
2001   desc_v[0] = "Auto account created by Moira";
2002   email_v[0] = user;
2003
2004   strcpy(new_dn, cn_user_name);
2005   n = 0;
2006   ADD_ATTR("cn", contact_v, LDAP_MOD_ADD);
2007   ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
2008   ADD_ATTR("name", name_v, LDAP_MOD_ADD);
2009   ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
2010   ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
2011   if (!strcmp(group_ou, contact_ou))
2012     {
2013       ADD_ATTR("mail", email_v, LDAP_MOD_ADD);
2014     }
2015   mods[n] = NULL;
2016
2017   rc = ldap_add_ext_s(ld, new_dn, mods, NULL, NULL);
2018   for (i = 0; i < n; i++)
2019     free(mods[i]);
2020   if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
2021     {
2022       n = 0;
2023       ADD_ATTR("cn", contact_v, LDAP_MOD_ADD);
2024       ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
2025       ADD_ATTR("name", name_v, LDAP_MOD_ADD);
2026       ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
2027       ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
2028       mods[n] = NULL;
2029       rc = ldap_add_ext_s(ld, new_dn, mods, NULL, NULL);
2030       for (i = 0; i < n; i++)
2031         free(mods[i]);
2032     }
2033   if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
2034     {
2035       com_err(whoami, 0, "could not create contact %s : %s",
2036               user, ldap_err2string(rc));
2037       return(-1);
2038     }
2039   return(0);
2040 }
2041
2042 int user_update(LDAP *ldap_handle, char *dn_path, char *user_name,
2043                 char *Uid, char *MitId)
2044 {
2045   LDAPMod   *mods[20];
2046   LK_ENTRY  *group_base;
2047   int  group_count;
2048   char distinguished_name[256];
2049   char *uid_v[] = {NULL, NULL};
2050   char *mitid_v[] = {NULL, NULL};
2051   char *homedir_v[] = {NULL, NULL};
2052   char *winProfile_v[] = {NULL, NULL};
2053   char *drives_v[] = {NULL, NULL};
2054   int  n;
2055   int  rc;
2056   int  i;
2057   char filter_exp[256];
2058   char *attr_array[3];
2059   char **hp;
2060   char path[256];
2061   char winPath[256];
2062   char winProfile[256];
2063
2064   if (!check_string(user_name))
2065     {
2066       com_err(whoami, 0, "invalid LDAP user name %s", user_name);
2067       return(-1);
2068     }
2069
2070   group_count = 0;
2071   group_base = NULL;
2072   sprintf(filter_exp, "(sAMAccountName=%s)", user_name);
2073   attr_array[0] = "cn";
2074   attr_array[1] = NULL;
2075   if ((rc = linklist_build(ldap_handle, dn_path, filter_exp, attr_array, 
2076                            &group_base, &group_count)) != 0)
2077     {
2078       com_err(whoami, 0, "LDAP server couldn't process user %s : %s",
2079               user_name, ldap_err2string(rc));
2080       return(rc);
2081     }
2082
2083   if (group_count != 1)
2084     {
2085       com_err(whoami, 0, "LDAP server unable to find user %s in AD",
2086               user_name);
2087       linklist_free(group_base);
2088       return(LDAP_NO_SUCH_OBJECT);
2089     }
2090   strcpy(distinguished_name, group_base->dn);
2091
2092   linklist_free(group_base);
2093   group_count = 0;
2094   n = 0;
2095   if (strlen(Uid) != 0)
2096     {
2097       uid_v[0] = Uid;
2098       ADD_ATTR("uid", uid_v, LDAP_MOD_REPLACE);
2099       ADD_ATTR("uidNumber", uid_v, LDAP_MOD_REPLACE);
2100     }
2101   if (strlen(MitId) != 0)
2102     {
2103       mitid_v[0] = MitId;
2104       ADD_ATTR("employeeID", mitid_v, LDAP_MOD_REPLACE);
2105     }
2106   if ((hp = hes_resolve(user_name, "filsys")) != NULL)
2107     {
2108       memset(path, 0, sizeof(path));
2109       memset(winPath, 0, sizeof(winPath));
2110       sscanf(hp[0], "%*s %s", path);
2111       if (strlen(path) && strnicmp(path, AFS, strlen(AFS)) == 0)
2112         {
2113           AfsToWinAfs(path, winPath);
2114           homedir_v[0] = winPath;
2115           ADD_ATTR("homeDirectory", homedir_v, LDAP_MOD_REPLACE);
2116           strcpy(winProfile, winPath);
2117           strcat(winProfile, "\\.winprofile");
2118           winProfile_v[0] = winProfile;
2119           ADD_ATTR("profilePath", winProfile_v, LDAP_MOD_REPLACE);
2120           drives_v[0] = "H:";
2121           ADD_ATTR("homeDrive", drives_v, LDAP_MOD_REPLACE);
2122         }
2123     }
2124   mods[n] = NULL;
2125   if (n != 0)
2126     {
2127       if ((rc = ldap_modify_s(ldap_handle, distinguished_name, mods)) != LDAP_SUCCESS)
2128         {
2129           com_err(whoami, 0, "Couldn't modify user data for %s : %s",
2130                   user_name, ldap_err2string(rc));
2131         }
2132       for (i = 0; i < n; i++)
2133         free(mods[i]);
2134     }
2135   if (hp != NULL)
2136     {
2137       i = 0;
2138       while (hp[i])
2139         {
2140           free(hp[i]);
2141           i++;
2142         }
2143     }
2144
2145   return(rc);
2146 }
2147
2148 int user_rename(LDAP *ldap_handle, char *dn_path, char *before_user_name, 
2149                 char *user_name, char *Uid, char *MitId, int State)
2150 {
2151   LDAPMod *mods[20];
2152   char new_dn[256];
2153   char old_dn[256];
2154   char upn[256];
2155   char temp[128];
2156   char *userPrincipalName_v[] = {NULL, NULL};
2157   char *altSecurityIdentities_v[] = {NULL, NULL};
2158   char *name_v[] = {NULL, NULL};
2159   char *samAccountName_v[] = {NULL, NULL};
2160   char *uid_v[] = {NULL, NULL};
2161   char *mitid_v[] = {NULL, NULL};
2162   int  n;
2163   int  rc;
2164   int  i;
2165
2166   if ((State != US_REGISTERED) && (State != US_NO_PASSWD) && (State != US_ENROLL_NOT_ALLOWED))
2167     return(-1);
2168
2169   if (!check_string(before_user_name))
2170     {
2171       com_err(whoami, 0, "invalid LDAP user name %s", before_user_name);
2172       return(-1);
2173     }
2174   if (!check_string(user_name))
2175     {
2176       com_err(whoami, 0, "invalid LDAP user name %s", user_name);
2177       return(-1);
2178     }
2179
2180   strcpy(user_name, user_name);
2181   sprintf(old_dn, "cn=%s,%s,%s", before_user_name, user_ou, dn_path);
2182   sprintf(new_dn, "cn=%s", user_name);
2183   if ((rc = ldap_rename_s(ldap_handle, old_dn, new_dn, NULL, TRUE, 
2184                            NULL, NULL)) != LDAP_SUCCESS)
2185     {
2186       if (rc != LDAP_NO_SUCH_OBJECT)
2187         com_err(whoami, 0, "Couldn't rename user from %s to %s : %s",
2188                 before_user_name, user_name, ldap_err2string(rc));
2189       return(rc);
2190     }
2191
2192   name_v[0] = user_name;
2193   sprintf(upn, "%s@%s", user_name, ldap_domain);
2194   userPrincipalName_v[0] = upn;
2195   sprintf(temp, "Kerberos:%s@%s", user_name, PRIMARY_REALM);
2196   altSecurityIdentities_v[0] = temp;
2197   samAccountName_v[0] = user_name;
2198
2199   n = 0;
2200   ADD_ATTR("altSecurityIdentities", altSecurityIdentities_v, LDAP_MOD_REPLACE);
2201   ADD_ATTR("userPrincipalName", userPrincipalName_v, LDAP_MOD_REPLACE);
2202   ADD_ATTR("displayName", name_v, LDAP_MOD_REPLACE);
2203   ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_REPLACE);
2204   if (strlen(Uid) != 0)
2205     {
2206       uid_v[0] = Uid;
2207       ADD_ATTR("uid", uid_v, LDAP_MOD_REPLACE);
2208       ADD_ATTR("uidNumber", uid_v, LDAP_MOD_REPLACE);
2209     }
2210   if (strlen(MitId) != 0)
2211     {
2212       mitid_v[0] = MitId;
2213       ADD_ATTR("employeeID", mitid_v, LDAP_MOD_REPLACE);
2214     }
2215   mods[n] = NULL;
2216   sprintf(new_dn, "cn=%s,%s,%s", user_name, user_ou, dn_path);
2217   if ((rc = ldap_modify_s(ldap_handle, new_dn, mods)) != LDAP_SUCCESS)
2218     {
2219       com_err(whoami, 0, "After renaming, couldn't modify user data for %s : %s",
2220               user_name, ldap_err2string(rc));
2221     }
2222   for (i = 0; i < n; i++)
2223     free(mods[i]);
2224   return(rc);
2225 }
2226
2227 int filesys_process(LDAP *ldap_handle, char *dn_path, char *fs_name, 
2228                     char *fs_type, char *fs_pack, int operation)
2229 {
2230   char  distinguished_name[256];
2231   char  winPath[256];
2232   char  winProfile[256];
2233   char  filter_exp[256];
2234   char  *attr_array[3];
2235   char  *homedir_v[] = {NULL, NULL};
2236   char  *winProfile_v[] = {NULL, NULL};
2237   char  *drives_v[] = {NULL, NULL};
2238   int   group_count;
2239   int   n;
2240   int   rc;
2241   int   i;
2242   LDAPMod   *mods[20];
2243   LK_ENTRY  *group_base;
2244
2245   if (!check_string(fs_name))
2246     {
2247       com_err(whoami, 0, "invalid filesys name %s", fs_name);
2248       return(-1);
2249     }
2250
2251   if (strcmp(fs_type, "AFS"))
2252     {
2253       com_err(whoami, 0, "invalid filesys type %s", fs_type);
2254       return(-1);
2255     }
2256
2257   group_count = 0;
2258   group_base = NULL;
2259   sprintf(filter_exp, "(sAMAccountName=%s)", fs_name);
2260   attr_array[0] = "cn";
2261   attr_array[1] = NULL;
2262   if ((rc = linklist_build(ldap_handle, dn_path, filter_exp, attr_array, 
2263                            &group_base, &group_count)) != 0)
2264     {
2265       com_err(whoami, 0, "LDAP server couldn't process filesys %s : %s",
2266               fs_name, ldap_err2string(rc));
2267       return(rc);
2268     }
2269
2270   if (group_count != 1)
2271     {
2272       linklist_free(group_base);
2273       com_err(whoami, 0, "LDAP server unable to find user %s in AD",
2274               fs_name);
2275       return(LDAP_NO_SUCH_OBJECT);
2276     }
2277   strcpy(distinguished_name, group_base->dn);
2278   linklist_free(group_base);
2279   group_count = 0;
2280
2281   n = 0;
2282   if (operation == LDAP_MOD_ADD)
2283     {
2284       memset(winPath, 0, sizeof(winPath));
2285       AfsToWinAfs(fs_pack, winPath);
2286       homedir_v[0] = winPath;
2287       drives_v[0] = "H:";
2288       memset(winProfile, 0, sizeof(winProfile));
2289       strcpy(winProfile, winPath);
2290       strcat(winProfile, "\\.winprofile");
2291       winProfile_v[0] = winProfile;
2292     }
2293   else
2294     {
2295       homedir_v[0] = NULL;
2296       drives_v[0] = NULL;
2297       winProfile_v[0] = NULL;
2298     }
2299   ADD_ATTR("profilePath", winProfile_v, operation);
2300   ADD_ATTR("homeDrive", drives_v, operation);
2301   ADD_ATTR("homeDirectory", homedir_v, operation);
2302   mods[n] = NULL;
2303
2304   rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
2305   if (rc != LDAP_SUCCESS)
2306     {
2307       com_err(whoami, 0, "Couldn't modify user data for filesys %s : %s",
2308               fs_name, ldap_err2string(rc));
2309     }
2310   for (i = 0; i < n; i++)
2311     free(mods[i]);
2312
2313   return(rc);
2314 }
2315
2316 int user_create(int ac, char **av, void *ptr)
2317 {
2318   LK_ENTRY  *group_base;
2319   LDAPMod *mods[20];
2320   char new_dn[256];
2321   char user_name[256];
2322   char sam_name[256];
2323   char upn[256];
2324   char *cn_v[] = {NULL, NULL};
2325   char *objectClass_v[] = {"top", "person", 
2326                            "organizationalPerson", 
2327                            "user", NULL};
2328
2329   char *samAccountName_v[] = {NULL, NULL};
2330   char *altSecurityIdentities_v[] = {NULL, NULL};
2331   char *name_v[] = {NULL, NULL};
2332   char *desc_v[] = {NULL, NULL};
2333   char *userPrincipalName_v[] = {NULL, NULL};
2334   char *userAccountControl_v[] = {NULL, NULL};
2335   char *uid_v[] = {NULL, NULL};
2336   char *mitid_v[] = {NULL, NULL};
2337   char userAccountControlStr[80];
2338   char temp[128];
2339   u_int userAccountControl = UF_NORMAL_ACCOUNT | UF_DONT_EXPIRE_PASSWD | UF_PASSWD_CANT_CHANGE;
2340   int  n;
2341   int  rc;
2342   int  i;
2343   int  group_count;
2344   char filter_exp[256];
2345   char *attr_array[3];
2346   char **call_args;
2347
2348   call_args = ptr;
2349
2350   if ((atoi(av[U_STATE]) != US_REGISTERED) && (atoi(av[U_STATE]) != US_NO_PASSWD) && 
2351       (atoi(av[U_STATE]) != US_ENROLL_NOT_ALLOWED))
2352     {
2353       callback_rc = -1;
2354       return(-1);
2355     }
2356   if (!strncmp(av[U_NAME], "#", 1))
2357     {
2358       callback_rc = -1;
2359       return(-1);
2360     }
2361   if (!check_string(av[U_NAME]))
2362     {
2363       callback_rc = -1;
2364       com_err(whoami, 0, "invalid LDAP user name %s", av[U_NAME]);
2365       return(-1);
2366     }
2367
2368   strcpy(user_name, av[U_NAME]);
2369   sprintf(upn, "%s@%s", user_name, ldap_domain);
2370   sprintf(sam_name, "%s", av[U_NAME]);
2371   samAccountName_v[0] = sam_name;
2372   if (atoi(av[U_STATE]) == US_DELETED)
2373     userAccountControl |= UF_ACCOUNTDISABLE;
2374   sprintf(userAccountControlStr, "%ld", userAccountControl);
2375   userAccountControl_v[0] = userAccountControlStr;
2376   userPrincipalName_v[0] = upn;
2377
2378   cn_v[0] = user_name;
2379   name_v[0] = user_name;
2380   desc_v[0] = "Auto account created by Moira";
2381   sprintf(temp, "Kerberos:%s@%s", user_name, PRIMARY_REALM);
2382   altSecurityIdentities_v[0] = temp;    
2383   sprintf(new_dn, "cn=%s,%s,%s", user_name, user_ou, call_args[1]);
2384
2385   n = 0;
2386   ADD_ATTR("cn", cn_v, LDAP_MOD_ADD);
2387   ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
2388   ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_ADD);
2389   ADD_ATTR("userPrincipalName", userPrincipalName_v, LDAP_MOD_ADD);
2390   ADD_ATTR("userAccountControl", userAccountControl_v, LDAP_MOD_ADD);
2391   ADD_ATTR("name", name_v, LDAP_MOD_ADD);
2392   ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
2393   ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
2394   ADD_ATTR("altSecurityIdentities", altSecurityIdentities_v, LDAP_MOD_ADD);
2395   if (strlen(av[U_UID]) != 0)
2396     {
2397       uid_v[0] = av[U_UID];
2398       ADD_ATTR("uid", uid_v, LDAP_MOD_ADD);
2399       ADD_ATTR("uidNumber", uid_v, LDAP_MOD_ADD);
2400     }
2401   if (strlen(av[U_MITID]) != 0)
2402       mitid_v[0] = av[U_MITID];
2403   else
2404       mitid_v[0] = "none";
2405   ADD_ATTR("employeeID", mitid_v, LDAP_MOD_ADD);
2406   mods[n] = NULL;
2407
2408   rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL);
2409   for (i = 0; i < n; i++)
2410     free(mods[i]);
2411   if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
2412     {
2413       com_err(whoami, 0, "could not create user %s : %s",
2414               user_name, ldap_err2string(rc));
2415       callback_rc = rc;
2416       return(rc);
2417     }
2418   if (rc == LDAP_ALREADY_EXISTS)
2419     {
2420       UserReactivate = 1;
2421       rc = user_change_status((LDAP *)call_args[0], call_args[1], av[U_NAME], MEMBER_ACTIVATE);
2422       return(0);
2423     }
2424   if (rc == LDAP_SUCCESS)
2425     {
2426       if ((rc = set_password(sam_name, "", ldap_domain)) != 0)
2427         {
2428           com_err(whoami, 0, "Couldn't set password for user %s : %ld",
2429                   user_name, rc);
2430         }
2431     }
2432   sprintf(filter_exp, "(sAMAccountName=%s)", av[U_NAME]);
2433   attr_array[0] = "objectSid";
2434   attr_array[1] = NULL;
2435   group_count = 0;
2436   group_base = NULL;
2437   if ((rc = linklist_build((LDAP *)call_args[0], call_args[1], filter_exp, attr_array, 
2438                            &group_base, &group_count)) == LDAP_SUCCESS)
2439     {
2440       if (group_count == 1)
2441         {
2442           (*sid_ptr) = group_base;
2443           (*sid_ptr)->member = strdup(av[L_NAME]);
2444           (*sid_ptr)->type = (char *)GROUPS;
2445           sid_ptr = &(*sid_ptr)->next;
2446         }
2447       else
2448         {
2449           if (group_base != NULL)
2450             linklist_free(group_base);
2451         }
2452     }
2453   else
2454     {
2455       if (group_base != NULL)
2456         linklist_free(group_base);
2457     }
2458   return(0);
2459 }
2460
2461 int user_change_status(LDAP *ldap_handle, char *dn_path, char *user_name, int operation)
2462 {
2463   char      filter_exp[1024];
2464   char      *attr_array[3];
2465   char      temp[256];
2466   char      distinguished_name[1024];
2467   char      **modvalues;
2468   LDAPMod   *mods[20];
2469   LK_ENTRY  *group_base;
2470   int       group_count;
2471   int       rc;
2472   int       i;
2473   int       n;
2474   ULONG     ulongValue;
2475
2476   if (!check_string(user_name))
2477     {
2478       com_err(whoami, 0, "invalid LDAP user name %s", user_name);
2479       return(-1);
2480     }
2481
2482   group_count = 0;
2483   group_base = NULL;
2484   sprintf(filter_exp, "(sAMAccountName=%s)", user_name);
2485   attr_array[0] = "UserAccountControl";
2486   attr_array[1] = NULL;
2487   if ((rc = linklist_build(ldap_handle, dn_path, filter_exp, attr_array, 
2488                            &group_base, &group_count)) != 0)
2489     {
2490       com_err(whoami, 0, "LDAP server couldn't process user %s : %s",
2491               user_name, ldap_err2string(rc));
2492       return(rc);
2493     }
2494
2495   if (group_count != 1)
2496     {
2497       linklist_free(group_base);
2498       com_err(whoami, 0, "LDAP server unable to find user %s in AD",
2499               user_name);
2500       return(LDAP_NO_SUCH_OBJECT);
2501     }
2502
2503   strcpy(distinguished_name, group_base->dn);
2504   ulongValue = atoi((*group_base).value);
2505   if (operation == MEMBER_DEACTIVATE)
2506     ulongValue |= UF_ACCOUNTDISABLE;
2507   else    
2508     ulongValue &= ~UF_ACCOUNTDISABLE;
2509   sprintf(temp, "%ld", ulongValue);
2510   if ((rc = construct_newvalues(group_base, group_count, (*group_base).value, 
2511                                 temp, &modvalues, REPLACE)) == 1)
2512     goto cleanup;
2513   linklist_free(group_base);
2514   group_base = NULL;
2515   group_count = 0;
2516   n = 0;
2517   ADD_ATTR("UserAccountControl", modvalues, LDAP_MOD_REPLACE);
2518   mods[n] = NULL;
2519   rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
2520   for (i = 0; i < n; i++)
2521     free(mods[i]);
2522   free_values(modvalues);
2523   if (rc != LDAP_SUCCESS)
2524     {
2525       com_err(whoami, 0, "LDAP server could not change status of user %s : %s",
2526               user_name, ldap_err2string(rc));
2527     }
2528 cleanup:
2529   return(rc);
2530 }
2531
2532 int user_delete(LDAP *ldap_handle, char *dn_path, char *u_name)
2533 {
2534   char      filter_exp[1024];
2535   char      *attr_array[3];
2536   char      distinguished_name[1024];
2537   char      user_name[512];
2538   LK_ENTRY  *group_base;
2539   int       group_count;
2540   int       rc;
2541
2542   if (!check_string(u_name))
2543     return(0);
2544   strcpy(user_name, u_name);
2545   group_count = 0;
2546   group_base = NULL;
2547   sprintf(filter_exp, "(sAMAccountName=%s)", user_name);
2548   attr_array[0] = "name";
2549   attr_array[1] = NULL;
2550   if ((rc = linklist_build(ldap_handle, dn_path, filter_exp, attr_array, 
2551                            &group_base, &group_count)) != 0)
2552     {
2553       com_err(whoami, 0, "LDAP server couldn't process user %s : %s",
2554               user_name, ldap_err2string(rc));
2555       goto cleanup;
2556     }
2557
2558   if (group_count != 1)
2559     {
2560       com_err(whoami, 0, "LDAP server unable to find user %s in AD",
2561               user_name);
2562       goto cleanup;
2563     }
2564
2565   strcpy(distinguished_name, group_base->dn);
2566   if (rc = ldap_delete_s(ldap_handle, distinguished_name))
2567     {
2568       com_err(whoami, 0, "LDAP server couldn't process user %s : %s",
2569               user_name, ldap_err2string(rc));
2570     }
2571
2572 cleanup:
2573   linklist_free(group_base);
2574   return(0);
2575 }
2576
2577 void linklist_free(LK_ENTRY *linklist_base)
2578 {
2579   LK_ENTRY *linklist_previous;
2580
2581   while (linklist_base != NULL)
2582     {
2583       if (linklist_base->dn != NULL)
2584         free(linklist_base->dn);
2585       if (linklist_base->attribute != NULL)
2586         free(linklist_base->attribute);
2587       if (linklist_base->value != NULL)
2588         free(linklist_base->value);
2589       if (linklist_base->member != NULL)
2590         free(linklist_base->member);
2591       if (linklist_base->type != NULL)
2592         free(linklist_base->type);
2593       if (linklist_base->list != NULL)
2594         free(linklist_base->list);
2595       linklist_previous = linklist_base;
2596       linklist_base = linklist_previous->next;
2597       free(linklist_previous);
2598     }
2599 }
2600
2601 void free_values(char **modvalues)
2602 {
2603   int i;
2604
2605   i = 0;
2606   if (modvalues != NULL)
2607     {
2608     while (modvalues[i] != NULL)
2609       {
2610         free(modvalues[i]);
2611         modvalues[i] = NULL;
2612         ++i;
2613       }
2614     free(modvalues);
2615   }
2616 }
2617
2618 int sid_update(LDAP *ldap_handle, char *dn_path)
2619 {
2620   LK_ENTRY      *ptr;
2621   int           rc;
2622   unsigned char temp[126];
2623   char          *av[3];
2624
2625   ptr = sid_base;
2626
2627   while (ptr != NULL)
2628     {
2629       memset(temp, 0, sizeof(temp));
2630       convert_b_to_a(temp, ptr->value, ptr->length);
2631       if (!ptr->member)
2632         continue;
2633       av[0] = ptr->member;
2634       av[1] = temp;
2635       if (ptr->type == (char *)GROUPS)
2636         {
2637           ptr->type = NULL;
2638           rc = mr_query("add_list_sid_by_name", 2, av, NULL, NULL);
2639         }
2640       else if (ptr->type == (char *)USERS)
2641         {
2642           ptr->type = NULL;
2643           rc = mr_query("add_user_sid_by_login", 2, av, NULL, NULL);
2644         }
2645       ptr = ptr->next;
2646     }
2647   return(0);
2648 }
2649
2650 void convert_b_to_a(char *string, UCHAR *binary, int length)
2651 {
2652   int   i;
2653   int   j;
2654   UCHAR tmp;
2655
2656   j = 0;
2657   for (i = 0; i < length; i++)
2658     {
2659       tmp = binary[i];
2660       string[j] = tmp;
2661       string[j] >>= 4;
2662       string[j] &= 0x0f;
2663       string[j] += 0x30;
2664       if (string[j] > '9')
2665         string[j] += 0x27;
2666       ++j;
2667       string[j] = tmp & 0x0f;
2668       string[j] += 0x30;
2669       if (string[j] > '9')
2670         string[j] += 0x27;
2671       j++;
2672     }
2673   string[j] = 0;
2674 }
2675
2676 static int illegalchars[] = {
2677   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^@ - ^O */
2678   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^P - ^_ */
2679   1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, /* SPACE - / */
2680   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, /* 0 - ? */
2681   0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* @ - O */
2682   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, /* P - _ */
2683   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ` - o */
2684   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, /* p - ^? */
2685   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2686   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2687   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2688   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2689   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2690   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2691   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2692   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2693 };
2694
2695 int check_string(char *s)
2696 {
2697   char  character;
2698
2699   for (; *s; s++)
2700     {
2701       character = *s;
2702       if (isupper(character))
2703         character = tolower(character);
2704       if (illegalchars[(unsigned) character])
2705         return 0;
2706     }
2707   return 1;
2708 }
2709
2710 int mr_connect_cl(char *server, char *client, int version, int auth)
2711 {
2712   int   status;
2713   char  *motd;
2714   char  temp[128];
2715
2716   status = mr_connect(server);
2717   if (status)
2718     {
2719       com_err(whoami, status, "while connecting to Moira");
2720       return status;
2721     }
2722
2723   status = mr_motd(&motd);
2724   if (status)
2725     {
2726       mr_disconnect();
2727       com_err(whoami, status, "while checking server status");
2728       return status;
2729     }
2730   if (motd)
2731     {
2732       sprintf(temp, "The Moira server is currently unavailable: %s", motd);
2733       com_err(whoami, status, temp);
2734       mr_disconnect();
2735       return status;
2736     }
2737
2738   status = mr_version(version);
2739   if (status)
2740     {
2741       if (status == MR_UNKNOWN_PROC)
2742         {
2743           if (version > 2)
2744             status = MR_VERSION_HIGH;
2745           else
2746             status = MR_SUCCESS;
2747         }
2748
2749       if (status == MR_VERSION_HIGH)
2750         {
2751           com_err(whoami, 0, "Warning: This client is running newer code than the server.");
2752                   com_err(whoami, 0, "Some operations may not work.");
2753         }
2754       else if (status && status != MR_VERSION_LOW)
2755         {
2756           com_err(whoami, status, "while setting query version number.");
2757           mr_disconnect();
2758           return status;
2759         }
2760     }
2761
2762   if (auth)
2763     {
2764       status = mr_auth(client);
2765       if (status)
2766         {
2767           com_err(whoami, status, "while authenticating to Moira.");
2768           mr_disconnect();
2769           return status;
2770         }
2771     }
2772
2773   return MR_SUCCESS;
2774 }
2775
2776 void AfsToWinAfs(char* path, char* winPath)
2777 {
2778     char* pathPtr;
2779     char* winPathPtr;
2780     strcpy(winPath, WINAFS);
2781     pathPtr = path + strlen(AFS);
2782     winPathPtr = winPath + strlen(WINAFS);
2783
2784     while (*pathPtr)
2785     {
2786         if (*pathPtr == '/')
2787           *winPathPtr = '\\';
2788         else
2789           *winPathPtr = *pathPtr;
2790
2791         pathPtr++;
2792         winPathPtr++;
2793     }
2794 }
This page took 0.34918 seconds and 5 git commands to generate.