]> andersk Git - moira.git/blob - incremental/winad/winad.c
8c04a2091b583c18bb6e3f3b67a8e423b6b8a105
[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,
249                  char *after_group_name, char *after_group_membership, 
250                  char *after_group_ou, int after_security_flag);
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         {
615           if (astatus && bstatus)
616             {
617               com_err(whoami, 0, "Changing list name from %s to %s",
618                       before[L_NAME], after[L_NAME]);
619               if ((strlen(before_group_ou) == 0) || (strlen(before_group_membership) == 0) ||
620                   (strlen(group_ou) == 0) || (strlen(group_membership) == 0))
621                 {
622                   com_err(whoami, 0, "%s", "couldn't find the group OU's");
623                   return;
624                 }
625               if ((rc = group_rename(ldap_handle, dn_path, 
626                                      before[L_NAME], before_group_membership, 
627                                      before_group_ou, before_security_flag,
628                                      after[L_NAME], group_membership, 
629                                      group_ou, security_flag)) != LDAP_NO_SUCH_OBJECT)
630                 {
631                   if (rc != LDAP_SUCCESS)
632                     com_err(whoami, 0, "Could not change list name from %s to %s",
633                                     before[L_NAME], 
634                                     after[L_NAME]);
635                   return;
636                 }
637               bgid = 0;
638             }
639           if (!agid)
640             return;
641         }
642       else
643         bgid = 0;
644     }
645
646   if (bgid)
647     {
648       if ((strlen(before_group_ou) == 0) || (strlen(before_group_membership) == 0))
649         {
650           com_err(whoami, 0, "couldn't find the group OU for group %s", before[L_NAME]);
651           return;
652         }
653       com_err(whoami, 0, "Deleting group %s", before[L_NAME]);
654       rc = group_delete(ldap_handle, dn_path, before[L_NAME], before_group_membership);
655       return;
656     }
657   if (agid)
658     {
659       com_err(whoami, 0, "Creating group %s", after[L_NAME]);
660
661       if (rc = moira_connect())
662         {
663           critical_alert("AD incremental",
664                          "Error contacting Moira server : %s",
665                          error_message(rc));
666           return;
667         }
668
669       av[0] = after[L_NAME];
670       call_args[0] = (char *)ldap_handle;
671       call_args[1] = dn_path;
672       call_args[2] = after[L_NAME];
673       call_args[3] = (char *)(MOIRA_USERS | MOIRA_KERBEROS | MOIRA_STRINGS);
674       call_args[4] = NULL;
675       sid_base = NULL;
676       sid_ptr = &sid_base;
677       callback_rc = 0;
678       if (rc = mr_query("get_list_info", 1, av, group_create, call_args))
679         {
680           moira_disconnect();
681           com_err(whoami, 0, "Couldn't create list %s : %s", after[L_NAME], error_message(rc));
682           return;
683         }
684       if (callback_rc)
685         {
686           moira_disconnect();
687           com_err(whoami, 0, "Couldn't create list %s", after[L_NAME]);
688           return;
689         }
690
691       if (sid_base != NULL)
692         {
693           sid_update(ldap_handle, dn_path);
694           linklist_free(sid_base);
695           sid_base = NULL;
696         }
697
698       sleep(1);
699       com_err(whoami, 0, "Populating group %s", after[L_NAME]);
700       av[0] = after[L_NAME];
701       call_args[0] = (char *)ldap_handle;
702       call_args[1] = dn_path;
703       call_args[2] = after[L_NAME];
704       call_args[3] = (char *)(MOIRA_USERS | MOIRA_KERBEROS | MOIRA_STRINGS);
705       call_args[4] = NULL;
706       member_base = NULL;
707       if (rc = mr_query("get_end_members_of_list", 1, av,
708                         member_list_build, call_args))
709         {
710           moira_disconnect();
711           com_err(whoami, 0, "Couldn't populate list %s : %s", 
712                   after[L_NAME], error_message(rc));
713           return;
714         }
715       if (member_base != NULL)
716         {
717           ptr = member_base;
718           while (ptr != NULL)
719             {
720               if (!strcasecmp(ptr->type, "LIST"))
721                 {
722                   ptr = ptr->next;
723                   continue;
724                 }
725               pUserOu = user_ou;
726               if (!strcasecmp(ptr->type, "STRING"))
727                 {
728                   if (contact_create(ldap_handle, dn_path, ptr->member, contact_ou))
729                     return;
730                   pUserOu = contact_ou;
731                 }
732               else if (!strcasecmp(ptr->type, "KERBEROS"))
733                 {
734                   if (contact_create(ldap_handle, dn_path, ptr->member, kerberos_ou))
735                     return;
736                   pUserOu = kerberos_ou;
737                 }
738               rc = member_add(ldap_handle, dn_path, after[L_NAME],
739                               group_ou, group_membership, ptr->member, pUserOu);
740               ptr = ptr->next;
741             }
742           linklist_free(member_base);
743           member_base = NULL;
744         }
745       moira_disconnect();
746     }
747
748   return;
749 }
750
751 #define LM_EXTRA_ACTIVE   (LM_END)
752 #define LM_EXTRA_PUBLIC   (LM_END+1)
753 #define LM_EXTRA_HIDDEN   (LM_END+2)
754 #define LM_EXTRA_MAILLIST (LM_END+3)
755 #define LM_EXTRA_GROUP    (LM_END+4)
756 #define LM_EXTRA_GID      (LM_END+5)
757 #define LM_EXTRA_END      (LM_END+6)
758
759 void do_member(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
760                char **before, int beforec, char **after, int afterc)
761 {
762   char  group_name[128];
763   char  user_name[128];
764   char  user_type[128];
765   int   rc;
766   char  group_membership[1];
767   int   security_flag;
768   char  group_ou[256];
769   char  *args[16];
770   char  **ptr;
771   char  *pUserOu;
772
773   pUserOu = NULL;
774   ptr = NULL;
775   if (afterc)
776     {
777       if (afterc < LM_EXTRA_END)
778         return;
779       if (!atoi(after[LM_EXTRA_ACTIVE]))
780         return;
781       ptr = after;
782       strcpy(user_name, after[LM_MEMBER]);
783       strcpy(group_name, after[LM_LIST]);
784       strcpy(user_type, after[LM_TYPE]);
785
786     }
787   else if (beforec)
788     {
789       if (beforec < LM_EXTRA_END)
790         return;
791       if (!atoi(before[LM_EXTRA_ACTIVE]))
792           return;
793       ptr = before;
794       strcpy(user_name, before[LM_MEMBER]);
795       strcpy(group_name, before[LM_LIST]);
796       strcpy(user_type, before[LM_TYPE]);
797     }
798
799   if (ptr == NULL)
800     return;
801
802   args[L_NAME] = ptr[LM_LIST];
803   args[L_ACTIVE] = ptr[LM_EXTRA_ACTIVE];
804   args[L_PUBLIC] = ptr[LM_EXTRA_PUBLIC];
805   args[L_HIDDEN] = ptr[LM_EXTRA_HIDDEN];
806   args[L_MAILLIST] = ptr[LM_EXTRA_MAILLIST];
807   args[L_GROUP] = ptr[LM_EXTRA_GROUP];
808   args[L_GID] = ptr[LM_EXTRA_GID];
809
810   security_flag = 0;
811   memset(group_ou, '\0', sizeof(group_ou));
812   get_group_membership(group_membership, group_ou, &security_flag, args);
813   if (strlen(group_ou) == 0)
814     {
815       com_err(whoami, 0, "couldn't find the group OU for group %s", group_name);
816       return;
817     }
818
819   rc = 0;
820   if (beforec)
821     {
822       if (!strcasecmp(ptr[LM_TYPE], "LIST"))
823         return;
824
825       com_err(whoami, 0, "Removing user %s from list %s", user_name, group_name);
826       pUserOu = user_ou;
827       if (!strcasecmp(ptr[LM_TYPE], "STRING"))
828         {
829           if (contact_create(ldap_handle, dn_path, ptr[LM_MEMBER], contact_ou))
830             return;
831           pUserOu = contact_ou;
832         }
833       else if (!strcasecmp(ptr[LM_TYPE], "KERBEROS"))
834         {
835           if (contact_create(ldap_handle, dn_path, ptr[LM_MEMBER], kerberos_ou))
836             return;
837           pUserOu = kerberos_ou;
838         }
839       rc = member_remove(ldap_handle, dn_path, group_name,
840                        group_ou, group_membership, ptr[LM_MEMBER], pUserOu);
841     }
842   else
843     {
844       if (!strcasecmp(ptr[LM_TYPE], "LIST"))
845         return;
846
847       com_err(whoami, 0, "Adding user %s to list %s", user_name, group_name);
848       pUserOu = user_ou;
849       if (!strcasecmp(ptr[LM_TYPE], "STRING"))
850         {
851           if (contact_create(ldap_handle, dn_path, ptr[LM_MEMBER], contact_ou))
852             return;
853           pUserOu = contact_ou;
854         }
855       else if (!strcasecmp(ptr[LM_TYPE], "KERBEROS"))
856         {
857           if (contact_create(ldap_handle, dn_path, ptr[LM_MEMBER], kerberos_ou))
858             return;
859           pUserOu = kerberos_ou;
860         }
861       rc = member_add(ldap_handle, dn_path, group_name,
862                       group_ou, group_membership, ptr[LM_MEMBER], pUserOu);
863     }
864   if (rc)
865     {
866       if (afterc)
867         com_err(whoami, 0, "Couldn't add %s to group %s", user_name, group_name);
868       else
869         com_err(whoami, 0, "Couldn't remove %s to group %s", user_name, group_name);
870     }
871   return;
872 }
873
874
875 void do_user(LDAP *ldap_handle, char *dn_path, char *ldap_hostname, 
876              char **before, int beforec, char **after, 
877              int afterc)
878 {
879   int   rc;
880   char  *av[2];
881   char  *call_args[6];
882   int   astate;
883   int   bstate;
884
885   if ((beforec == 0) && (afterc == 0))
886     return;
887
888   astate = 0;
889   bstate = 0;
890   if (afterc > U_STATE)
891     astate = atoi(after[U_STATE]);
892   if (beforec > U_STATE)
893     bstate = atoi(before[U_STATE]);
894
895   if (astate == 2)
896     astate = 1;
897   if (bstate == 2)
898     bstate = 1;
899
900   if ((bstate == 0) && (astate == 0))
901     return;
902
903   if (astate == bstate)
904     {
905       if (!strcmp(before[U_NAME], after[U_NAME]))
906         {
907           com_err(whoami, 0, "Updating user %s info", before[U_NAME]);
908           rc = user_update(ldap_handle, dn_path, before[U_NAME],
909                            before[U_UID], before[U_MITID]);
910           return;
911         }
912       else
913         {
914           com_err(whoami, 0, "Changing user %s to %s", before[U_NAME],
915                   after[U_NAME]);
916           if ((rc = user_rename(ldap_handle, dn_path, before[U_NAME], 
917                 after[U_NAME], after[U_UID], after[U_MITID], 
918                 atoi(after[U_STATE]))) != LDAP_NO_SUCH_OBJECT)
919             {
920               if (rc != LDAP_SUCCESS)
921                 {
922                   com_err(whoami, 0, "Could not change user %s to %s : %s",
923                           before[U_NAME], 
924                           after[U_NAME], error_message(rc));
925                 }
926               return;
927             }
928         }
929       bstate = 0;
930     }
931
932   if (bstate == 1)
933     {
934       com_err(whoami, 0, "Deactivate user %s in the AD", before[U_NAME]);
935
936       if ((rc = user_change_status(ldap_handle, dn_path, before[U_NAME], 
937                                    MEMBER_DEACTIVATE)) != LDAP_SUCCESS)
938         {
939           com_err(whoami, 0, "Couldn't deactivate user %s in the AD", before[U_NAME]);
940         }
941       return;
942     }
943
944   if (astate == 1)
945     {
946       if (rc = moira_connect())
947         {
948           critical_alert("AD incremental", 
949                          "Error connection to Moira : %s",
950                          error_message(rc));
951           return;
952         }
953       com_err(whoami, 0, "Creating/Reactivating user %s", after[U_NAME]);
954
955       av[0] = after[U_NAME];
956       call_args[0] = (char *)ldap_handle;
957       call_args[1] = dn_path;
958       call_args[2] = (char *)MEMBER_ACTIVATE;
959       call_args[3] = NULL;
960       sid_base = NULL;
961       sid_ptr = &sid_base;
962       UserReactivate = 0;
963       callback_rc = 0;
964       if (rc = mr_query("get_user_account_by_login", 1, av, user_create,
965                         call_args))
966         {
967           moira_disconnect();
968           com_err(whoami, 0, "Couldn't create/activate user %s : %s",
969                   after[U_NAME], error_message(rc));
970           return;
971         }
972       if (callback_rc)
973         {
974           moira_disconnect();
975           com_err(whoami, 0, "Couldn't create/activate user %s", after[U_NAME]);
976           return;
977         }
978       sleep(1);
979       if (sid_base != NULL)
980         {
981           sid_update(ldap_handle, dn_path);
982           linklist_free(sid_base);
983         }
984       if (UserReactivate)
985         {
986           av[0] = "ruser";
987           av[1] = after[U_NAME];
988           call_args[0] = (char *)ldap_handle;
989           call_args[1] = dn_path;
990           call_args[2] = after[U_NAME];
991           call_args[3] = user_ou;
992           rc = mr_query("get_lists_of_member", 2, av, process_lists,
993                           call_args);
994           if (rc && rc != MR_NO_MATCH)
995             {
996               com_err(whoami, 0, "Couldn't retrieve membership of user %s: %s",
997                       after[U_NAME], error_message(rc));
998             }
999         }
1000       moira_disconnect();
1001     }
1002
1003   return;
1004 }
1005
1006 int construct_newvalues(LK_ENTRY *linklist_base, int modvalue_count, 
1007                         char *oldValue, char *newValue,
1008                         char ***modvalues, int type)
1009 {
1010   LK_ENTRY    *linklist_ptr;
1011   int         i;
1012   char        *cPtr;
1013
1014   if (((*modvalues) = calloc(1, (modvalue_count + 1) * sizeof(char *)))
1015       == NULL)
1016     {
1017       return(1);
1018     }
1019   for (i = 0; i < (modvalue_count + 1); i++)
1020     (*modvalues)[i] = NULL;
1021   if (modvalue_count != 0)
1022     {
1023       linklist_ptr = linklist_base;
1024       for (i = 0; i < modvalue_count; i++)
1025         {
1026           if ((oldValue != NULL) && (newValue != NULL))
1027             {
1028               if ((cPtr = (char *)strstr(linklist_ptr->value, oldValue))
1029                  != (char *)NULL)
1030                 {
1031                   if (type == REPLACE)
1032                     {
1033                       if (((*modvalues)[i] = calloc(1, strlen(newValue) + 1))
1034                           == NULL)
1035                         return(1);
1036                       memset((*modvalues)[i], '\0', strlen(newValue) + 1);
1037                       strcpy((*modvalues)[i], newValue);
1038                     }
1039                   else
1040                     {
1041                       if (((*modvalues)[i] = calloc(1, 
1042                                         (int)(cPtr - linklist_ptr->value) + 
1043                                         (linklist_ptr->length - strlen(oldValue)) + 
1044                                         strlen(newValue) + 1)) == NULL)
1045                         return(1);
1046                       memset((*modvalues)[i], '\0', 
1047                              (int)(cPtr - linklist_ptr->value) + 
1048                              (linklist_ptr->length - strlen(oldValue)) + 
1049                              strlen(newValue) + 1);
1050                       memcpy((*modvalues)[i], linklist_ptr->value, 
1051                              (int)(cPtr - linklist_ptr->value));
1052                       strcat((*modvalues)[i], newValue);
1053                       strcat((*modvalues)[i], 
1054      &linklist_ptr->value[(int)(cPtr - linklist_ptr->value) + strlen(oldValue)]);
1055                     }
1056                 }
1057               else
1058                 {
1059                   (*modvalues)[i] = calloc(1, linklist_ptr->length + 1);
1060                   memset((*modvalues)[i], '\0', linklist_ptr->length + 1);
1061                   memcpy((*modvalues)[i], linklist_ptr->value,
1062                          linklist_ptr->length);
1063                 }
1064             }
1065         else
1066             {
1067               (*modvalues)[i] = calloc(1, linklist_ptr->length + 1);
1068               memset((*modvalues)[i], '\0', linklist_ptr->length + 1);
1069               memcpy((*modvalues)[i], linklist_ptr->value,
1070                      linklist_ptr->length);
1071             }
1072           linklist_ptr = linklist_ptr->next;
1073         }
1074       (*modvalues)[i] = NULL;
1075     }
1076   return(0);
1077 }
1078
1079
1080 int linklist_build(LDAP *ldap_handle, char *dn_path, char *search_exp, 
1081                    char **attr_array, LK_ENTRY **linklist_base,
1082                    int *linklist_count)
1083 {
1084   ULONG       rc;
1085   LDAPMessage *ldap_entry;
1086
1087   rc = 0;
1088   ldap_entry = NULL;
1089   (*linklist_base) = NULL;
1090   (*linklist_count) = 0;
1091   if ((rc = ldap_search_s(ldap_handle, dn_path, LDAP_SCOPE_SUBTREE, 
1092                           search_exp, attr_array, 0, &ldap_entry))
1093       != LDAP_SUCCESS)
1094     return(0);
1095   rc = retrieve_entries(ldap_handle, ldap_entry, linklist_base, linklist_count);
1096
1097   ldap_msgfree(ldap_entry);
1098   return(rc);
1099 }
1100
1101
1102 int retrieve_entries(LDAP *ldap_handle, LDAPMessage *ldap_entry, 
1103                      LK_ENTRY **linklist_base, int *linklist_count)
1104 {
1105   char        distinguished_name[1024];
1106   LK_ENTRY    *linklist_ptr;
1107   int         rc;
1108
1109   if ((ldap_entry = ldap_first_entry(ldap_handle, ldap_entry)) == NULL)
1110     return(0);
1111
1112   memset(distinguished_name, '\0', sizeof(distinguished_name));
1113   get_distinguished_name(ldap_handle, ldap_entry, distinguished_name);
1114
1115   if ((rc = retrieve_attributes(ldap_handle, ldap_entry, distinguished_name,
1116                                 linklist_base)) != 0)
1117     return(rc);
1118
1119   while ((ldap_entry = ldap_next_entry(ldap_handle, ldap_entry)) != NULL)
1120     {
1121       memset(distinguished_name, '\0', sizeof(distinguished_name));
1122       get_distinguished_name(ldap_handle, ldap_entry, distinguished_name);
1123
1124       if ((rc = retrieve_attributes(ldap_handle, ldap_entry, distinguished_name,
1125                                     linklist_base)) != 0)
1126         return(rc);
1127     }
1128
1129   linklist_ptr = (*linklist_base);
1130   (*linklist_count) = 0;
1131   while (linklist_ptr != NULL)
1132     {
1133       ++(*linklist_count);
1134       linklist_ptr = linklist_ptr->next;
1135     }
1136   return(0);
1137 }
1138
1139 int retrieve_attributes(LDAP *ldap_handle, LDAPMessage *ldap_entry, 
1140                         char *distinguished_name, LK_ENTRY **linklist_current)
1141 {
1142   char        *Attribute;
1143   BerElement  *ptr;
1144
1145   ptr = NULL;
1146   if ((Attribute = ldap_first_attribute(ldap_handle, ldap_entry, &ptr)) != NULL)
1147     {
1148       retrieve_values(ldap_handle, ldap_entry, Attribute, distinguished_name,
1149                       linklist_current);
1150       ldap_memfree(Attribute);
1151       while ((Attribute = ldap_next_attribute(ldap_handle, ldap_entry, 
1152                                               ptr)) != NULL)
1153         {
1154           retrieve_values(ldap_handle, ldap_entry, Attribute,
1155                           distinguished_name, linklist_current);
1156           ldap_memfree(Attribute);
1157         }
1158     }
1159   ldap_ber_free(ptr, 0);
1160   return(0);
1161 }
1162
1163 int retrieve_values(LDAP *ldap_handle, LDAPMessage *ldap_entry,
1164                     char *Attribute, char *distinguished_name,
1165                     LK_ENTRY **linklist_current)
1166 {
1167   char        **str_value;
1168   char        temp[256];
1169   void        **Ptr;
1170   int         use_bervalue;
1171   LK_ENTRY    *linklist_previous;
1172   LDAP_BERVAL **ber_value;
1173   DWORD       ber_length;
1174 #ifdef LDAP_DEBUG
1175   SID         *sid;
1176   GUID        *guid;
1177   int         i;
1178   int         intValue;
1179   DWORD       *subauth;
1180   SID_IDENTIFIER_AUTHORITY    *sid_auth;
1181   unsigned char   *subauth_count;
1182 #endif /*LDAP_BEGUG*/
1183
1184   use_bervalue = 0;
1185   memset(temp, '\0', sizeof(temp));
1186   if ((!strcmp(Attribute, "objectSid")) ||
1187       (!strcmp(Attribute, "objectGUID")))
1188     use_bervalue = 1;
1189
1190   if (use_bervalue)
1191     {
1192       ber_value = ldap_get_values_len(ldap_handle, ldap_entry, Attribute);
1193       Ptr = (void **)ber_value;
1194       str_value = NULL;
1195       }
1196   else
1197     {
1198       str_value = ldap_get_values(ldap_handle, ldap_entry, Attribute);
1199       Ptr = (void **)str_value;
1200       ber_value = NULL;
1201     }
1202   if (Ptr != NULL)
1203     {
1204       for (; *Ptr; Ptr++) 
1205         {
1206           if ((linklist_previous = calloc(1, sizeof(LK_ENTRY))) == NULL)
1207             return(1);
1208           memset(linklist_previous, '\0', sizeof(LK_ENTRY));
1209           linklist_previous->next = (*linklist_current);
1210           (*linklist_current) = linklist_previous;
1211
1212           if (((*linklist_current)->attribute = calloc(1, 
1213                                                strlen(Attribute) + 1)) == NULL)
1214             return(1);
1215           memset((*linklist_current)->attribute, '\0', strlen(Attribute) + 1);
1216           strcpy((*linklist_current)->attribute, Attribute);
1217           if (use_bervalue)
1218             {
1219               ber_length = (*(LDAP_BERVAL **)Ptr)->bv_len;
1220               if (((*linklist_current)->value = calloc(1, ber_length)) == NULL)
1221                 return(1);
1222               memset((*linklist_current)->value, '\0', ber_length);
1223               memcpy((*linklist_current)->value, (*(LDAP_BERVAL **)Ptr)->bv_val, 
1224                                                   ber_length);
1225               (*linklist_current)->length = ber_length;
1226             }
1227           else
1228             {
1229               if (((*linklist_current)->value = calloc(1, 
1230                                                   strlen(*Ptr) + 1)) == NULL)
1231                 return(1);
1232               memset((*linklist_current)->value, '\0', strlen(*Ptr) + 1);
1233               (*linklist_current)->length = strlen(*Ptr);
1234               strcpy((*linklist_current)->value, *Ptr);
1235             }
1236           (*linklist_current)->ber_value = use_bervalue;
1237           if (((*linklist_current)->dn = calloc(1, 
1238                                       strlen(distinguished_name) + 1)) == NULL)
1239             return(1);
1240           memset((*linklist_current)->dn, '\0', strlen(distinguished_name) + 1);
1241           strcpy((*linklist_current)->dn, distinguished_name);
1242
1243 #ifdef LDAP_DEBUG
1244           if (!strcmp(Attribute, "objectGUID"))
1245             {
1246               guid = (GUID *)((*linklist_current)->value);
1247               sprintf(temp, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", 
1248                       guid->Data1, guid->Data2, guid->Data3, 
1249                       guid->Data4[0], guid->Data4[1], guid->Data4[2], 
1250                       guid->Data4[3], guid->Data4[4], guid->Data4[5], 
1251                       guid->Data4[6], guid->Data4[7]);
1252               print_to_screen("     %20s : {%s}\n", Attribute, temp);
1253             }
1254           else if (!strcmp(Attribute, "objectSid"))
1255             {
1256               sid = (SID *)((*(LDAP_BERVAL **)Ptr)->bv_val);
1257 #ifdef _WIN32
1258               print_to_screen("        Revision = %d\n", sid->Revision);
1259               print_to_screen("        SID Identifier Authority:\n");
1260               sid_auth = &sid->IdentifierAuthority;
1261               if (sid_auth->Value[0])
1262                 print_to_screen("            SECURITY_NULL_SID_AUTHORITY\n");
1263               else if (sid_auth->Value[1])
1264                 print_to_screen("            SECURITY_WORLD_SID_AUTHORITY\n");
1265               else if (sid_auth->Value[2])
1266                 print_to_screen("            SECURITY_LOCAL_SID_AUTHORITY\n");
1267               else if (sid_auth->Value[3])
1268                 print_to_screen("            SECURITY_CREATOR_SID_AUTHORITY\n");
1269               else if (sid_auth->Value[5])
1270                 print_to_screen("            SECURITY_NT_AUTHORITY\n");
1271               else
1272                 print_to_screen("            UNKNOWN SID AUTHORITY\n");
1273               subauth_count = GetSidSubAuthorityCount(sid);
1274               print_to_screen("        SidSubAuthorityCount = %d\n", 
1275                               *subauth_count);
1276               print_to_screen("        SidSubAuthority:\n");
1277               for (i = 0; i < *subauth_count; i++)
1278                 {
1279                   if ((subauth = GetSidSubAuthority(sid, i)) != NULL)
1280                     print_to_screen("            %u\n", *subauth);
1281                 }
1282 #endif
1283             }
1284           else if ((!memcmp(Attribute, "userAccountControl", 
1285                             strlen("userAccountControl"))) ||
1286                    (!memcmp(Attribute, "sAMAccountType", 
1287                             strlen("sAmAccountType"))))
1288             {
1289               intValue = atoi(*Ptr);
1290               print_to_screen("     %20s : %ld\n",Attribute, intValue);
1291               if (!memcmp(Attribute, "userAccountControl", 
1292                           strlen("userAccountControl")))
1293                 {
1294                   if (intValue & UF_ACCOUNTDISABLE)
1295                     print_to_screen("     %20s :    %s\n", 
1296                                     "", "Account disabled");
1297                   else
1298                     print_to_screen("     %20s :    %s\n", 
1299                                     "", "Account active");
1300                   if (intValue & UF_HOMEDIR_REQUIRED)
1301                     print_to_screen("     %20s :    %s\n", 
1302                                     "", "Home directory required");
1303                   if (intValue & UF_LOCKOUT)
1304                     print_to_screen("     %20s :    %s\n", 
1305                                     "", "Account locked out");
1306                   if (intValue & UF_PASSWD_NOTREQD)
1307                     print_to_screen("     %20s :    %s\n", 
1308                                     "", "No password required");
1309                   if (intValue & UF_PASSWD_CANT_CHANGE)
1310                     print_to_screen("     %20s :    %s\n",
1311                                     "", "Cannot change password");
1312                   if (intValue & UF_TEMP_DUPLICATE_ACCOUNT)
1313                     print_to_screen("     %20s :    %s\n", 
1314                                     "", "Temp duplicate account");
1315                   if (intValue & UF_NORMAL_ACCOUNT)
1316                     print_to_screen("     %20s :    %s\n", 
1317                                     "", "Normal account");
1318                   if (intValue & UF_INTERDOMAIN_TRUST_ACCOUNT)
1319                     print_to_screen("     %20s :    %s\n", 
1320                                     "", "Interdomain trust account");
1321                   if (intValue & UF_WORKSTATION_TRUST_ACCOUNT)
1322                     print_to_screen("     %20s :    %s\n", 
1323                                     "", "Workstation trust account");
1324                   if (intValue & UF_SERVER_TRUST_ACCOUNT)
1325                     print_to_screen("     %20s :    %s\n", 
1326                                     "", "Server trust account");
1327                 }
1328             }
1329           else
1330             {
1331               print_to_screen("     %20s : %s\n",Attribute, *Ptr);
1332             }
1333 #endif /*LDAP_DEBUG*/
1334         }
1335       if (str_value != NULL)
1336         ldap_value_free(str_value);
1337       if (ber_value != NULL)
1338         ldap_value_free_len(ber_value);
1339     }
1340   (*linklist_current) = linklist_previous;
1341   return(0);
1342 }
1343
1344 int moira_connect(void)
1345 {
1346   long    rc;
1347   char    HostName[64];
1348
1349   if (!mr_connections++)
1350     {
1351 #ifdef _WIN32
1352       memset(HostName, '\0', sizeof(HostName));
1353       strcpy(HostName, "ttsp");
1354       rc = mr_connect_cl(HostName, "winad.incr", QUERY_VERSION, 1);
1355 /*det
1356       rc = mr_connect(HostName);
1357 */
1358 #else
1359       struct utsname uts;
1360       uname(&uts);
1361       rc = mr_connect_cl(uts.nodename, "winad.incr", QUERY_VERSION, 1);
1362 /*
1363       rc = mr_connect(uts.nodename);
1364 */
1365 #endif /*WIN32*/
1366 /*det
1367       if (!rc)
1368         rc = mr_auth("winad.incr");
1369 */
1370       return rc;
1371     }
1372   return 0;
1373 }
1374
1375 void check_winad(void)
1376 {
1377   int i;
1378   
1379   for (i = 0; file_exists(STOP_FILE); i++)
1380     {
1381       if (i > 30)
1382         {
1383           critical_alert("AD incremental",
1384                          "WINAD incremental failed (%s exists): %s",
1385                          STOP_FILE, tbl_buf);
1386           exit(1);
1387         }
1388       sleep(60);
1389     }
1390 }
1391
1392 int moira_disconnect(void)
1393 {
1394
1395   if (!--mr_connections)
1396     {
1397       mr_disconnect();
1398     }
1399   return 0;
1400 }
1401
1402 void get_distinguished_name(LDAP *ldap_handle, LDAPMessage *ldap_entry, 
1403                             char *distinguished_name)
1404 {
1405   char    *CName;
1406
1407   CName = ldap_get_dn(ldap_handle, ldap_entry);
1408   if (CName == NULL)
1409     return;
1410   strcpy(distinguished_name, CName);
1411   ldap_memfree(CName);
1412 }
1413
1414 int linklist_create_entry(char *attribute, char *value, 
1415                           LK_ENTRY **linklist_entry)
1416 {
1417   (*linklist_entry) = calloc(1, sizeof(LK_ENTRY));
1418   if (!(*linklist_entry))
1419     {
1420       return(1);
1421     }
1422   memset((*linklist_entry), '\0', sizeof(LK_ENTRY));
1423   (*linklist_entry)->attribute = calloc(1, strlen(attribute) + 1);
1424   memset((*linklist_entry)->attribute, '\0', strlen(attribute) + 1);
1425   strcpy((*linklist_entry)->attribute, attribute);
1426   (*linklist_entry)->value = calloc(1, strlen(value) + 1);
1427   memset((*linklist_entry)->value, '\0', strlen(value) + 1);
1428   strcpy((*linklist_entry)->value, value);
1429   (*linklist_entry)->length = strlen(value);
1430   (*linklist_entry)->next = NULL;
1431   return(0);
1432 }
1433
1434 void print_to_screen(const char *fmt, ...)
1435 {
1436   va_list pvar;
1437
1438   va_start(pvar, fmt);
1439   vfprintf(stderr, fmt, pvar);
1440   fflush(stderr);
1441   va_end(pvar);
1442 }
1443
1444 int get_group_membership(char *group_membership, char *group_ou, 
1445                          int *security_flag, char **av)
1446 {
1447   int  maillist_flag;
1448   int  group_flag;
1449
1450   maillist_flag = atoi(av[L_MAILLIST]);
1451   group_flag = atoi(av[L_GROUP]);
1452   if (security_flag != NULL)
1453     (*security_flag) = 0;
1454
1455   if ((maillist_flag) && (group_flag))
1456     {
1457       if (group_membership != NULL)
1458         group_membership[0] = 'B';
1459       if (security_flag != NULL)
1460         (*security_flag) = 1;
1461       if (group_ou != NULL)
1462         strcpy(group_ou, group_ou_both);
1463     }
1464   else if ((!maillist_flag) && (group_flag))
1465     {
1466       if (group_membership != NULL)
1467         group_membership[0] = 'S';
1468       if (security_flag != NULL)
1469         (*security_flag) = 1;
1470       if (group_ou != NULL)
1471         strcpy(group_ou, group_ou_security);
1472     }
1473   else if ((maillist_flag) && (!group_flag))
1474     {
1475       if (group_membership != NULL)
1476         group_membership[0] = 'D';
1477       if (group_ou != NULL)
1478         strcpy(group_ou, group_ou_distribution);
1479     }
1480   else
1481     {
1482       if (group_membership != NULL)
1483         group_membership[0] = 'N';
1484       if (group_ou != NULL)
1485         strcpy(group_ou, group_ou_neither);
1486     }
1487   return(0);
1488 }
1489
1490 int group_rename(LDAP *ldap_handle, char *dn_path, 
1491                  char *before_group_name, char *before_group_membership, 
1492                  char *before_group_ou, int before_security_flag,
1493                  char *after_group_name, char *after_group_membership, 
1494                  char *after_group_ou, int after_security_flag)
1495 {
1496   LDAPMod   *mods[20];
1497   char      old_dn[512];
1498   char      new_dn[512];
1499   char      new_dn_path[512];
1500   char      sam_name[256];
1501   char      filter_exp[4096];
1502   char      *attr_array[3];
1503   char      *name_v[] = {NULL, NULL};
1504   char      *samAccountName_v[] = {NULL, NULL};
1505   int       n;
1506   int       i;
1507   int       rc;
1508   LK_ENTRY  *group_base;
1509   int       group_count;
1510
1511   if (!check_string(before_group_name))
1512     {
1513       com_err(whoami, 0, "invalid LDAP list name %s", before_group_name);
1514       return(-1);
1515     }
1516   if (!check_string(after_group_name))
1517     {
1518       com_err(whoami, 0, "invalid LDAP list name %s", after_group_name);
1519       return(-1);
1520     }
1521
1522   sprintf(filter_exp, "(sAMAccountName=%s_zZx%c)", before_group_name, before_group_membership[0]);
1523   attr_array[0] = "distinguishedName";
1524   attr_array[1] = NULL;
1525   if ((rc = linklist_build(ldap_handle, dn_path, filter_exp, attr_array, 
1526                            &group_base, &group_count)) != 0)
1527     {
1528       com_err(whoami, 0, "LDAP server unable to get list %s dn : %s",
1529               after_group_name, ldap_err2string(rc));
1530       return(rc);
1531     }
1532   if (group_count != 1)
1533     {
1534       com_err(whoami, 0, "LDAP server unable to find list %s in AD",
1535               after_group_name);
1536       callback_rc = LDAP_NO_SUCH_OBJECT;
1537       return(-1);
1538     }
1539   strcpy(old_dn, group_base->value);
1540   linklist_free(group_base);
1541   group_base = NULL;
1542   group_count = 0;
1543
1544   sprintf(sam_name, "%s_zZx%c", after_group_name, after_group_membership[0]);
1545   sprintf(new_dn_path, "%s,%s", after_group_ou, dn_path);
1546   sprintf(new_dn, "cn=%s", after_group_name);
1547   if ((rc = ldap_rename_s(ldap_handle, old_dn, new_dn, new_dn_path,
1548                           TRUE, NULL, NULL)) != LDAP_SUCCESS)
1549     {
1550       com_err(whoami, 0, "Couldn't rename list from %s to %s : %s",
1551               after_group_name, after_group_name, ldap_err2string(rc));
1552       return(rc);
1553     }
1554
1555   name_v[0] = after_group_name;
1556   samAccountName_v[0] = sam_name;
1557   n = 0;
1558   ADD_ATTR("displayName", name_v, LDAP_MOD_REPLACE);
1559   ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_REPLACE);
1560   mods[n] = NULL;
1561   sprintf(new_dn, "cn=%s,%s,%s", after_group_name, after_group_ou, dn_path);
1562   if ((rc = ldap_modify_s(ldap_handle, new_dn, mods)) != LDAP_SUCCESS)
1563     {
1564       com_err(whoami, 0, "After renaming, couldn't modify list data for %s : %s",
1565               after_group_name, ldap_err2string(rc));
1566     }
1567   for (i = 0; i < n; i++)
1568     free(mods[i]);
1569   return(rc);
1570 }
1571
1572 int group_create(int ac, char **av, void *ptr)
1573 {
1574   LDAPMod *mods[20];
1575   LK_ENTRY  *group_base;
1576   char new_dn[256];
1577   char group_ou[256];
1578   char new_group_name[256];
1579   char sam_group_name[256];
1580   char cn_group_name[256];
1581   char *cn_v[] = {NULL, NULL};
1582   char *objectClass_v[] = {"top", "group", NULL};
1583   char info[256];
1584   char *samAccountName_v[] = {NULL, NULL};
1585   char *managedBy_v[] = {NULL, NULL};
1586   char *altSecurityIdentities_v[] = {NULL, NULL};
1587   char *name_v[] = {NULL, NULL};
1588   char *desc_v[] = {NULL, NULL};
1589   char *info_v[] = {NULL, NULL};
1590   char *groupTypeControl_v[] = {NULL, NULL};
1591   char groupTypeControlStr[80];
1592   char group_membership[1];
1593   int  i;
1594   int  security_flag;
1595   u_int groupTypeControl = ADS_GROUP_TYPE_GLOBAL_GROUP;
1596   int  n;
1597   int  rc;
1598   int  group_count;
1599   char filter_exp[256];
1600   char *attr_array[3];
1601   char **call_args;
1602
1603   call_args = ptr;
1604
1605   if (!atoi(av[L_ACTIVE]))
1606     return(1);
1607   if (!check_string(av[L_NAME]))
1608     {
1609       com_err(whoami, 0, "invalid LDAP list name %s", av[L_NAME]);
1610       return(1);
1611     }
1612
1613   memset(group_ou, 0, sizeof(group_ou));
1614   memset(group_membership, 0, sizeof(group_membership));
1615   security_flag = 0;
1616   get_group_membership(group_membership, group_ou, &security_flag, av);
1617
1618   if (security_flag)
1619     groupTypeControl |= ADS_GROUP_TYPE_SECURITY_ENABLED;
1620   sprintf(groupTypeControlStr, "%ld", groupTypeControl);
1621   groupTypeControl_v[0] = groupTypeControlStr;
1622
1623   strcpy(new_group_name, av[L_NAME]);
1624   strcpy(cn_group_name, av[L_NAME]);
1625   sprintf(sam_group_name, "%s_zZx%c", av[L_NAME], group_membership[0]);
1626
1627   samAccountName_v[0] = sam_group_name;
1628   name_v[0] = new_group_name;
1629   cn_v[0] = new_group_name;
1630
1631   sprintf(new_dn, "cn=%s,%s,%s", new_group_name, group_ou, call_args[1]);
1632   n = 0;
1633   ADD_ATTR("cn", cn_v, LDAP_MOD_ADD);
1634   ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
1635   ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_ADD);
1636   ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
1637   ADD_ATTR("name", name_v, LDAP_MOD_ADD);
1638   if (strlen(av[L_DESC]) != 0)
1639     {
1640       desc_v[0] = av[L_DESC];
1641       ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
1642     }
1643   ADD_ATTR("groupType", groupTypeControl_v, LDAP_MOD_ADD);
1644   if (strlen(av[L_ACE_NAME]) != 0)
1645     {
1646       sprintf(info, "The Administrator of this list is the LIST: %s", av[L_ACE_NAME]);
1647       info_v[0] = info;
1648       ADD_ATTR("info", info_v, LDAP_MOD_ADD);
1649     }
1650   mods[n] = NULL;
1651
1652   rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL);
1653
1654   for (i = 0; i < n; i++)
1655     free(mods[i]);
1656   if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
1657     {
1658       com_err(whoami, 0, "Unable to create list %s in AD : %s",
1659               av[L_NAME], ldap_err2string(rc));
1660       callback_rc = rc;
1661       return(rc);
1662     }
1663   sprintf(filter_exp, "(sAMAccountName=%s)", sam_group_name);
1664   attr_array[0] = "objectSid";
1665   attr_array[1] = NULL;
1666   group_count = 0;
1667   group_base = NULL;
1668   if ((rc = linklist_build((LDAP *)call_args[0], call_args[1], filter_exp, attr_array, 
1669                            &group_base, &group_count)) == LDAP_SUCCESS)
1670     {
1671       if (group_count == 1)
1672         {
1673           (*sid_ptr) = group_base;
1674           (*sid_ptr)->member = strdup(av[L_NAME]);
1675           (*sid_ptr)->type = (char *)GROUPS;
1676           sid_ptr = &(*sid_ptr)->next;
1677         }
1678       else
1679         {
1680           if (group_base != NULL)
1681             linklist_free(group_base);
1682         }
1683     }
1684   else
1685     {
1686       if (group_base != NULL)
1687         linklist_free(group_base);
1688     }
1689   return(LDAP_SUCCESS);
1690 }
1691
1692 int group_delete(LDAP *ldap_handle, char *dn_path, char *group_name, char *group_membership)
1693 {
1694   LK_ENTRY  *group_base;
1695   char      *attr_array[3];
1696   char      filter_exp[1024];
1697   char      sam_group_name[256];
1698   char      temp[512];
1699   int       group_count;
1700   int       rc;
1701
1702   if (!check_string(group_name))
1703     {
1704       com_err(whoami, 0, "invalid LDAP list name %s", group_name);
1705       return(-1);
1706     }
1707   rc = 1;
1708   group_count = 0;
1709   group_base = NULL;
1710   attr_array[0] = "distinguishedName";
1711   attr_array[1] = NULL;
1712   strcpy(sam_group_name, group_name);
1713   sprintf(temp, "%s,%s", group_ou_root, dn_path);
1714   sprintf(filter_exp, "(sAMAccountName=%s_zZx%c)", group_name, group_membership[0]);
1715   if (linklist_build(ldap_handle, temp, filter_exp, attr_array, 
1716                            &group_base, &group_count) != 0)
1717     return(-1);
1718   if (group_count == 1)
1719     {
1720       if ((rc = ldap_delete_s(ldap_handle, group_base->value)) != LDAP_SUCCESS)
1721         {
1722           linklist_free(group_base);
1723           com_err(whoami, 0, "Unable to delete list %s from AD : %s",
1724                   group_name, ldap_err2string(rc));
1725           return(-1);
1726         }
1727       linklist_free(group_base);
1728     }
1729   else
1730     {
1731       linklist_free(group_base);
1732       com_err(whoami, 0, "Unable to find list %s in AD.", group_name);
1733       return(-1);
1734     }
1735
1736   return(0);
1737 }
1738
1739 int process_lists(int ac, char **av, void *ptr)
1740 {
1741   int   rc;
1742   int   security_flag;
1743   char  group_ou[256];
1744   char  group_membership[2];
1745   char  **call_args;
1746
1747   call_args = ptr;
1748
1749   security_flag = 0;
1750   memset(group_ou, '\0', sizeof(group_ou));
1751   memset(group_membership, '\0', sizeof(group_membership));
1752   get_group_membership(group_membership, group_ou, &security_flag, av);
1753   rc = member_add((LDAP *)call_args[0], (char *)call_args[1], av[L_NAME],
1754                   group_ou, group_membership, call_args[2],  (char *)call_args[3]);
1755   if (rc)
1756     {
1757       com_err(whoami, 0, "Couldn't add %s to group %s", call_args[2], av[L_NAME]);
1758     }
1759   return(0);
1760 }
1761
1762 int member_list_build(int ac, char **av, void *ptr)
1763 {
1764   LK_ENTRY  *linklist;
1765   char      temp[1024];
1766   char      **call_args;
1767
1768   call_args = ptr;
1769
1770   strcpy(temp, av[ACE_NAME]);
1771   if (!check_string(temp))
1772     return(0);
1773   if (!strcmp(av[ACE_TYPE], "USER"))
1774     {
1775       if (!((int)call_args[3] & MOIRA_USERS))
1776         return(0);
1777     }
1778   else if (!strcmp(av[ACE_TYPE], "STRING"))
1779     {
1780       if (!((int)call_args[3] & MOIRA_STRINGS))
1781         return(0);
1782       if (contact_create((LDAP *)call_args[0], call_args[1], temp, contact_ou))
1783         return(0);
1784     }
1785   else if (!strcmp(av[ACE_TYPE], "LIST"))
1786     {
1787       if (!((int)call_args[3] & MOIRA_LISTS))
1788         return(0);
1789     }
1790   else if (!strcmp(av[ACE_TYPE], "KERBEROS"))
1791     {
1792       if (!((int)call_args[3] & MOIRA_KERBEROS))
1793         return(0);
1794       if (contact_create((LDAP *)call_args[0], call_args[1], temp, kerberos_ou))
1795         return(0);
1796     }
1797   else
1798     return(0);
1799
1800   linklist = member_base;
1801   while (linklist)
1802     {
1803     if (!strcasecmp(temp, linklist->member))
1804       return(0);
1805     linklist = linklist->next;
1806     }
1807   linklist = calloc(1, sizeof(LK_ENTRY));
1808   linklist->op = 1;
1809   linklist->dn = NULL;
1810   linklist->list = calloc(1, strlen(call_args[2]) + 1);
1811   strcpy(linklist->list, call_args[2]);
1812   linklist->type = calloc(1, strlen(av[ACE_TYPE]) + 1);
1813   strcpy(linklist->type, av[ACE_TYPE]);
1814   linklist->member = calloc(1, strlen(temp) + 1);
1815   strcpy(linklist->member, temp);
1816   linklist->next = member_base;
1817   member_base = linklist;
1818   return(0);
1819 }
1820
1821 int member_remove(LDAP *ldap_handle, char *dn_path, char *group_name, 
1822                   char *group_ou, char *group_membership, char *user_name,
1823                   char *UserOu)
1824 {
1825   char        distinguished_name[1024];
1826   char        *modvalues[2];
1827   char        filter_exp[4096];
1828   char        *attr_array[3];
1829   char        temp[256];
1830   int         group_count;
1831   int         i;
1832   int         n;
1833   LDAPMod     *mods[20];
1834   LK_ENTRY    *group_base;
1835   ULONG       rc;
1836
1837   if (!check_string(group_name))
1838     return(1);
1839   strcpy(temp, group_name);
1840   sprintf(filter_exp, "(sAMAccountName=%s_zZx%c)", group_name, group_membership[0]);
1841   attr_array[0] = "distinguishedName";
1842   attr_array[1] = NULL;
1843   if ((rc = linklist_build(ldap_handle, dn_path, filter_exp, attr_array, 
1844                            &group_base, &group_count)) != 0)
1845     {
1846       com_err(whoami, 0, "LDAP server unable to get list %s info : %s",
1847               group_name, ldap_err2string(rc));
1848       goto cleanup;
1849     }
1850   if (group_count != 1)
1851     {
1852       com_err(whoami, 0, "LDAP server unable to find list %s in AD",
1853               group_name);
1854       linklist_free(group_base);
1855       group_base = NULL;
1856       group_count = 0;
1857       goto cleanup;
1858     }
1859   strcpy(distinguished_name, group_base->value);
1860   linklist_free(group_base);
1861   group_base = NULL;
1862   group_count = 0;
1863
1864   sprintf(temp, "CN=%s,%s,%s", user_name, UserOu, dn_path);
1865   modvalues[0] = temp;
1866   modvalues[1] = NULL;
1867
1868   n = 0;
1869   ADD_ATTR("member", modvalues, LDAP_MOD_DELETE);
1870   mods[n] = NULL;
1871   rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
1872   for (i = 0; i < n; i++)
1873     free(mods[i]);
1874   if (rc != LDAP_SUCCESS)
1875     {
1876       com_err(whoami, 0, "LDAP server unable to modify list %s members : %s",
1877               group_name, ldap_err2string(rc));
1878       goto cleanup;
1879     }
1880
1881 cleanup:
1882   return(rc);
1883 }
1884
1885 int member_add(LDAP *ldap_handle, char *dn_path, char *group_name, 
1886                char *group_ou, char *group_membership, char *user_name, char *UserOu)
1887 {
1888   char        distinguished_name[1024];
1889   char        *modvalues[2];
1890   char        filter_exp[4096];
1891   char        *attr_array[3];
1892   char        temp[256];
1893   int         group_count;
1894   int         n;
1895   int         i;
1896   LDAPMod     *mods[20];
1897   LK_ENTRY    *group_base;
1898   ULONG       rc;
1899
1900   rc = 0;
1901   group_base = NULL;
1902   group_count = 0;
1903
1904   if (!check_string(group_name))
1905     return(-1);
1906
1907   strcpy(temp, group_name);
1908   sprintf(filter_exp, "(sAMAccountName=%s_zZx%c)", group_name, group_membership[0]);
1909   attr_array[0] = "distinguishedName";
1910   attr_array[1] = NULL;
1911   if ((rc = linklist_build(ldap_handle, dn_path, filter_exp, attr_array, 
1912                            &group_base, &group_count)) != 0)
1913     {
1914       com_err(whoami, 0, "LDAP server unable to get list %s info : %s",
1915               group_name, ldap_err2string(rc));
1916       return(-1);
1917     }
1918   if (group_count != 1)
1919     {
1920       linklist_free(group_base);
1921       group_base = NULL;
1922       group_count = 0;
1923       com_err(whoami, 0, "LDAP server unable to find list %s in AD",
1924               group_name);
1925       return(-1);
1926     }
1927
1928   strcpy(distinguished_name, group_base->value);
1929   linklist_free(group_base);
1930   group_base = NULL;
1931   group_count = 0;
1932
1933   sprintf(temp, "CN=%s,%s,%s", user_name, UserOu, dn_path);
1934   modvalues[0] = temp;
1935   modvalues[1] = NULL;
1936
1937   n = 0;
1938   ADD_ATTR("member", modvalues, LDAP_MOD_ADD);
1939   mods[n] = NULL;
1940   rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
1941   if (rc == LDAP_ALREADY_EXISTS)
1942     rc = LDAP_SUCCESS;
1943   for (i = 0; i < n; i++)
1944     free(mods[i]);
1945   if (rc != LDAP_SUCCESS)
1946     {
1947       com_err(whoami, 0, "LDAP server unable to modify list %s members in AD : %s",
1948               group_name, ldap_err2string(rc));
1949     }
1950
1951   return(rc);
1952 }
1953
1954 int contact_create(LDAP *ld, char *bind_path, char *user, char *group_ou)
1955 {
1956   LDAPMod *mods[20];
1957   char new_dn[256];
1958   char cn_user_name[256];
1959   char contact_name[256];
1960   char *email_v[] = {NULL, NULL};
1961   char *cn_v[] = {NULL, NULL};
1962   char *contact_v[] = {NULL, NULL};
1963   char *objectClass_v[] = {"top", "person", 
1964                            "organizationalPerson", 
1965                            "contact", NULL};
1966   char *name_v[] = {NULL, NULL};
1967   char *desc_v[] = {NULL, NULL};
1968   int  n;
1969   int  rc;
1970   int  i;
1971
1972   if (!check_string(user))
1973     {
1974       com_err(whoami, 0, "invalid LDAP name %s", user);
1975       return(-1);
1976     }
1977   strcpy(contact_name, user);
1978   sprintf(cn_user_name,"CN=%s,%s,%s", contact_name, group_ou, bind_path);
1979   cn_v[0] = cn_user_name;
1980   contact_v[0] = contact_name;
1981   name_v[0] = user;
1982   desc_v[0] = "Auto account created by Moira";
1983   email_v[0] = user;
1984
1985   strcpy(new_dn, cn_user_name);
1986   n = 0;
1987   ADD_ATTR("cn", contact_v, LDAP_MOD_ADD);
1988   ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
1989   ADD_ATTR("name", name_v, LDAP_MOD_ADD);
1990   ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
1991   ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
1992   if (!strcmp(group_ou, contact_ou))
1993     {
1994       ADD_ATTR("mail", email_v, LDAP_MOD_ADD);
1995     }
1996   mods[n] = NULL;
1997
1998   rc = ldap_add_ext_s(ld, new_dn, mods, NULL, NULL);
1999   for (i = 0; i < n; i++)
2000     free(mods[i]);
2001   if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
2002     {
2003       n = 0;
2004       ADD_ATTR("cn", contact_v, LDAP_MOD_ADD);
2005       ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
2006       ADD_ATTR("name", name_v, LDAP_MOD_ADD);
2007       ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
2008       ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
2009       mods[n] = NULL;
2010       rc = ldap_add_ext_s(ld, new_dn, mods, NULL, NULL);
2011       for (i = 0; i < n; i++)
2012         free(mods[i]);
2013     }
2014   if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
2015     {
2016       com_err(whoami, 0, "could not create contact %s : %s",
2017               user, ldap_err2string(rc));
2018       return(-1);
2019     }
2020   return(0);
2021 }
2022
2023 int user_update(LDAP *ldap_handle, char *dn_path, char *user_name,
2024                 char *Uid, char *MitId)
2025 {
2026   LDAPMod   *mods[20];
2027   LK_ENTRY  *group_base;
2028   int  group_count;
2029   char distinguished_name[256];
2030   char *uid_v[] = {NULL, NULL};
2031   char *mitid_v[] = {NULL, NULL};
2032   char *homedir_v[] = {NULL, NULL};
2033   char *winProfile_v[] = {NULL, NULL};
2034   char *drives_v[] = {NULL, NULL};
2035   int  n;
2036   int  rc;
2037   int  i;
2038   char filter_exp[256];
2039   char *attr_array[3];
2040   char **hp;
2041   char path[256];
2042   char winPath[256];
2043   char winProfile[256];
2044
2045   if (!check_string(user_name))
2046     {
2047       com_err(whoami, 0, "invalid LDAP user name %s", user_name);
2048       return(-1);
2049     }
2050
2051   group_count = 0;
2052   group_base = NULL;
2053   sprintf(filter_exp, "(sAMAccountName=%s)", user_name);
2054   attr_array[0] = "cn";
2055   attr_array[1] = NULL;
2056   if ((rc = linklist_build(ldap_handle, dn_path, filter_exp, attr_array, 
2057                            &group_base, &group_count)) != 0)
2058     {
2059       com_err(whoami, 0, "LDAP server couldn't process user %s : %s",
2060               user_name, ldap_err2string(rc));
2061       return(rc);
2062     }
2063
2064   if (group_count != 1)
2065     {
2066       com_err(whoami, 0, "LDAP server unable to find user %s in AD",
2067               user_name);
2068       linklist_free(group_base);
2069       return(LDAP_NO_SUCH_OBJECT);
2070     }
2071   strcpy(distinguished_name, group_base->dn);
2072
2073   linklist_free(group_base);
2074   group_count = 0;
2075   n = 0;
2076   if (strlen(Uid) != 0)
2077     {
2078       uid_v[0] = Uid;
2079       ADD_ATTR("uid", uid_v, LDAP_MOD_REPLACE);
2080       ADD_ATTR("uidNumber", uid_v, LDAP_MOD_REPLACE);
2081     }
2082   if (strlen(MitId) != 0)
2083     {
2084       mitid_v[0] = MitId;
2085       ADD_ATTR("employeeID", mitid_v, LDAP_MOD_REPLACE);
2086     }
2087   if ((hp = hes_resolve(user_name, "filsys")) != NULL)
2088     {
2089       memset(path, 0, sizeof(path));
2090       memset(winPath, 0, sizeof(winPath));
2091       sscanf(hp[0], "%*s %s", path);
2092       if (strlen(path) && strnicmp(path, AFS, strlen(AFS)) == 0)
2093         {
2094           AfsToWinAfs(path, winPath);
2095           homedir_v[0] = winPath;
2096           ADD_ATTR("homeDirectory", homedir_v, LDAP_MOD_REPLACE);
2097           strcpy(winProfile, winPath);
2098           strcat(winProfile, "\\.winprofile");
2099           winProfile_v[0] = winProfile;
2100           ADD_ATTR("profilePath", winProfile_v, LDAP_MOD_REPLACE);
2101           drives_v[0] = "H:";
2102           ADD_ATTR("homeDrive", drives_v, LDAP_MOD_REPLACE);
2103         }
2104     }
2105   mods[n] = NULL;
2106   if (n != 0)
2107     {
2108       if ((rc = ldap_modify_s(ldap_handle, distinguished_name, mods)) != LDAP_SUCCESS)
2109         {
2110           com_err(whoami, 0, "Couldn't modify user data for %s : %s",
2111                   user_name, ldap_err2string(rc));
2112         }
2113       for (i = 0; i < n; i++)
2114         free(mods[i]);
2115     }
2116   if (hp != NULL)
2117     {
2118       i = 0;
2119       while (hp[i])
2120         {
2121           free(hp[i]);
2122           i++;
2123         }
2124     }
2125
2126   return(rc);
2127 }
2128
2129 int user_rename(LDAP *ldap_handle, char *dn_path, char *before_user_name, 
2130                 char *user_name, char *Uid, char *MitId, int State)
2131 {
2132   LDAPMod *mods[20];
2133   char new_dn[256];
2134   char old_dn[256];
2135   char upn[256];
2136   char temp[128];
2137   char *userPrincipalName_v[] = {NULL, NULL};
2138   char *altSecurityIdentities_v[] = {NULL, NULL};
2139   char *name_v[] = {NULL, NULL};
2140   char *samAccountName_v[] = {NULL, NULL};
2141   char *uid_v[] = {NULL, NULL};
2142   char *mitid_v[] = {NULL, NULL};
2143   int  n;
2144   int  rc;
2145   int  i;
2146
2147   if ((State != US_REGISTERED) && (State != US_NO_PASSWD) && (State != US_ENROLL_NOT_ALLOWED))
2148     return(-1);
2149
2150   if (!check_string(before_user_name))
2151     {
2152       com_err(whoami, 0, "invalid LDAP user name %s", before_user_name);
2153       return(-1);
2154     }
2155   if (!check_string(user_name))
2156     {
2157       com_err(whoami, 0, "invalid LDAP user name %s", user_name);
2158       return(-1);
2159     }
2160
2161   strcpy(user_name, user_name);
2162   sprintf(old_dn, "cn=%s,%s,%s", before_user_name, user_ou, dn_path);
2163   sprintf(new_dn, "cn=%s", user_name);
2164   if ((rc = ldap_rename_s(ldap_handle, old_dn, new_dn, NULL, TRUE, 
2165                            NULL, NULL)) != LDAP_SUCCESS)
2166     {
2167       if (rc != LDAP_NO_SUCH_OBJECT)
2168         com_err(whoami, 0, "Couldn't rename user from %s to %s : %s",
2169                 before_user_name, user_name, ldap_err2string(rc));
2170       return(rc);
2171     }
2172
2173   name_v[0] = user_name;
2174   sprintf(upn, "%s@%s", user_name, ldap_domain);
2175   userPrincipalName_v[0] = upn;
2176   sprintf(temp, "Kerberos:%s@%s", user_name, PRIMARY_REALM);
2177   altSecurityIdentities_v[0] = temp;
2178   samAccountName_v[0] = user_name;
2179
2180   n = 0;
2181   ADD_ATTR("altSecurityIdentities", altSecurityIdentities_v, LDAP_MOD_REPLACE);
2182   ADD_ATTR("userPrincipalName", userPrincipalName_v, LDAP_MOD_REPLACE);
2183   ADD_ATTR("displayName", name_v, LDAP_MOD_REPLACE);
2184   ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_REPLACE);
2185   if (strlen(Uid) != 0)
2186     {
2187       uid_v[0] = Uid;
2188       ADD_ATTR("uid", uid_v, LDAP_MOD_REPLACE);
2189       ADD_ATTR("uidNumber", uid_v, LDAP_MOD_REPLACE);
2190     }
2191   if (strlen(MitId) != 0)
2192     {
2193       mitid_v[0] = MitId;
2194       ADD_ATTR("employeeID", mitid_v, LDAP_MOD_REPLACE);
2195     }
2196   mods[n] = NULL;
2197   sprintf(new_dn, "cn=%s,%s,%s", user_name, user_ou, dn_path);
2198   if ((rc = ldap_modify_s(ldap_handle, new_dn, mods)) != LDAP_SUCCESS)
2199     {
2200       com_err(whoami, 0, "After renaming, couldn't modify user data for %s : %s",
2201               user_name, ldap_err2string(rc));
2202     }
2203   for (i = 0; i < n; i++)
2204     free(mods[i]);
2205   return(rc);
2206 }
2207
2208 int filesys_process(LDAP *ldap_handle, char *dn_path, char *fs_name, 
2209                     char *fs_type, char *fs_pack, int operation)
2210 {
2211   char  distinguished_name[256];
2212   char  winPath[256];
2213   char  winProfile[256];
2214   char  filter_exp[256];
2215   char  *attr_array[3];
2216   char  *homedir_v[] = {NULL, NULL};
2217   char  *winProfile_v[] = {NULL, NULL};
2218   char  *drives_v[] = {NULL, NULL};
2219   int   group_count;
2220   int   n;
2221   int   rc;
2222   int   i;
2223   LDAPMod   *mods[20];
2224   LK_ENTRY  *group_base;
2225
2226   if (!check_string(fs_name))
2227     {
2228       com_err(whoami, 0, "invalid filesys name %s", fs_name);
2229       return(-1);
2230     }
2231
2232   if (strcmp(fs_type, "AFS"))
2233     {
2234       com_err(whoami, 0, "invalid filesys type %s", fs_type);
2235       return(-1);
2236     }
2237
2238   group_count = 0;
2239   group_base = NULL;
2240   sprintf(filter_exp, "(sAMAccountName=%s)", fs_name);
2241   attr_array[0] = "cn";
2242   attr_array[1] = NULL;
2243   if ((rc = linklist_build(ldap_handle, dn_path, filter_exp, attr_array, 
2244                            &group_base, &group_count)) != 0)
2245     {
2246       com_err(whoami, 0, "LDAP server couldn't process filesys %s : %s",
2247               fs_name, ldap_err2string(rc));
2248       return(rc);
2249     }
2250
2251   if (group_count != 1)
2252     {
2253       linklist_free(group_base);
2254       com_err(whoami, 0, "LDAP server unable to find user %s in AD",
2255               fs_name);
2256       return(LDAP_NO_SUCH_OBJECT);
2257     }
2258   strcpy(distinguished_name, group_base->dn);
2259   linklist_free(group_base);
2260   group_count = 0;
2261
2262   n = 0;
2263   if (operation == LDAP_MOD_ADD)
2264     {
2265       memset(winPath, 0, sizeof(winPath));
2266       AfsToWinAfs(fs_pack, winPath);
2267       homedir_v[0] = winPath;
2268       drives_v[0] = "H:";
2269       memset(winProfile, 0, sizeof(winProfile));
2270       strcpy(winProfile, winPath);
2271       strcat(winProfile, "\\.winprofile");
2272       winProfile_v[0] = winProfile;
2273     }
2274   else
2275     {
2276       homedir_v[0] = NULL;
2277       drives_v[0] = NULL;
2278       winProfile_v[0] = NULL;
2279     }
2280   ADD_ATTR("profilePath", winProfile_v, operation);
2281   ADD_ATTR("homeDrive", drives_v, operation);
2282   ADD_ATTR("homeDirectory", homedir_v, operation);
2283   mods[n] = NULL;
2284
2285   rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
2286   if (rc != LDAP_SUCCESS)
2287     {
2288       com_err(whoami, 0, "Couldn't modify user data for filesys %s : %s",
2289               fs_name, ldap_err2string(rc));
2290     }
2291   for (i = 0; i < n; i++)
2292     free(mods[i]);
2293
2294   return(rc);
2295 }
2296
2297 int user_create(int ac, char **av, void *ptr)
2298 {
2299   LK_ENTRY  *group_base;
2300   LDAPMod *mods[20];
2301   char new_dn[256];
2302   char user_name[256];
2303   char sam_name[256];
2304   char upn[256];
2305   char *cn_v[] = {NULL, NULL};
2306   char *objectClass_v[] = {"top", "person", 
2307                            "organizationalPerson", 
2308                            "user", NULL};
2309
2310   char *samAccountName_v[] = {NULL, NULL};
2311   char *altSecurityIdentities_v[] = {NULL, NULL};
2312   char *name_v[] = {NULL, NULL};
2313   char *desc_v[] = {NULL, NULL};
2314   char *userPrincipalName_v[] = {NULL, NULL};
2315   char *userAccountControl_v[] = {NULL, NULL};
2316   char *uid_v[] = {NULL, NULL};
2317   char *mitid_v[] = {NULL, NULL};
2318   char userAccountControlStr[80];
2319   char temp[128];
2320   u_int userAccountControl = UF_NORMAL_ACCOUNT | UF_DONT_EXPIRE_PASSWD | UF_PASSWD_CANT_CHANGE;
2321   int  n;
2322   int  rc;
2323   int  i;
2324   int  group_count;
2325   char filter_exp[256];
2326   char *attr_array[3];
2327   char **call_args;
2328
2329   call_args = ptr;
2330
2331   if ((atoi(av[U_STATE]) != US_REGISTERED) && (atoi(av[U_STATE]) != US_NO_PASSWD) && 
2332       (atoi(av[U_STATE]) != US_ENROLL_NOT_ALLOWED))
2333     {
2334       callback_rc = -1;
2335       return(-1);
2336     }
2337   if (!strncmp(av[U_NAME], "#", 1))
2338     {
2339       callback_rc = -1;
2340       return(-1);
2341     }
2342   if (!check_string(av[U_NAME]))
2343     {
2344       callback_rc = -1;
2345       com_err(whoami, 0, "invalid LDAP user name %s", av[U_NAME]);
2346       return(-1);
2347     }
2348
2349   strcpy(user_name, av[U_NAME]);
2350   sprintf(upn, "%s@%s", user_name, ldap_domain);
2351   sprintf(sam_name, "%s", av[U_NAME]);
2352   samAccountName_v[0] = sam_name;
2353   if (atoi(av[U_STATE]) == US_DELETED)
2354     userAccountControl |= UF_ACCOUNTDISABLE;
2355   sprintf(userAccountControlStr, "%ld", userAccountControl);
2356   userAccountControl_v[0] = userAccountControlStr;
2357   userPrincipalName_v[0] = upn;
2358
2359   cn_v[0] = user_name;
2360   name_v[0] = user_name;
2361   desc_v[0] = "Auto account created by Moira";
2362   sprintf(temp, "Kerberos:%s@%s", user_name, PRIMARY_REALM);
2363   altSecurityIdentities_v[0] = temp;    
2364   sprintf(new_dn, "cn=%s,%s,%s", user_name, user_ou, call_args[1]);
2365
2366   n = 0;
2367   ADD_ATTR("cn", cn_v, LDAP_MOD_ADD);
2368   ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
2369   ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_ADD);
2370   ADD_ATTR("userPrincipalName", userPrincipalName_v, LDAP_MOD_ADD);
2371   ADD_ATTR("userAccountControl", userAccountControl_v, LDAP_MOD_ADD);
2372   ADD_ATTR("name", name_v, LDAP_MOD_ADD);
2373   ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
2374   ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
2375   ADD_ATTR("altSecurityIdentities", altSecurityIdentities_v, LDAP_MOD_ADD);
2376   if (strlen(av[U_UID]) != 0)
2377     {
2378       uid_v[0] = av[U_UID];
2379       ADD_ATTR("uid", uid_v, LDAP_MOD_ADD);
2380       ADD_ATTR("uidNumber", uid_v, LDAP_MOD_ADD);
2381     }
2382   if (strlen(av[U_MITID]) != 0)
2383       mitid_v[0] = av[U_MITID];
2384   else
2385       mitid_v[0] = "none";
2386   ADD_ATTR("employeeID", mitid_v, LDAP_MOD_ADD);
2387   mods[n] = NULL;
2388
2389   rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL);
2390   for (i = 0; i < n; i++)
2391     free(mods[i]);
2392   if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
2393     {
2394       com_err(whoami, 0, "could not create user %s : %s",
2395               user_name, ldap_err2string(rc));
2396       callback_rc = rc;
2397       return(rc);
2398     }
2399   if (rc == LDAP_ALREADY_EXISTS)
2400     {
2401       UserReactivate = 1;
2402       rc = user_change_status((LDAP *)call_args[0], call_args[1], av[U_NAME], MEMBER_ACTIVATE);
2403       return(0);
2404     }
2405   if (rc == LDAP_SUCCESS)
2406     {
2407       if ((rc = set_password(sam_name, "", ldap_domain)) != 0)
2408         {
2409           com_err(whoami, 0, "Couldn't set password for user %s : %ld",
2410                   user_name, rc);
2411         }
2412     }
2413   sprintf(filter_exp, "(sAMAccountName=%s)", av[U_NAME]);
2414   attr_array[0] = "objectSid";
2415   attr_array[1] = NULL;
2416   group_count = 0;
2417   group_base = NULL;
2418   if ((rc = linklist_build((LDAP *)call_args[0], call_args[1], filter_exp, attr_array, 
2419                            &group_base, &group_count)) == LDAP_SUCCESS)
2420     {
2421       if (group_count == 1)
2422         {
2423           (*sid_ptr) = group_base;
2424           (*sid_ptr)->member = strdup(av[L_NAME]);
2425           (*sid_ptr)->type = (char *)GROUPS;
2426           sid_ptr = &(*sid_ptr)->next;
2427         }
2428       else
2429         {
2430           if (group_base != NULL)
2431             linklist_free(group_base);
2432         }
2433     }
2434   else
2435     {
2436       if (group_base != NULL)
2437         linklist_free(group_base);
2438     }
2439   return(0);
2440 }
2441
2442 int user_change_status(LDAP *ldap_handle, char *dn_path, char *user_name, int operation)
2443 {
2444   char      filter_exp[1024];
2445   char      *attr_array[3];
2446   char      temp[256];
2447   char      distinguished_name[1024];
2448   char      **modvalues;
2449   LDAPMod   *mods[20];
2450   LK_ENTRY  *group_base;
2451   int       group_count;
2452   int       rc;
2453   int       i;
2454   int       n;
2455   ULONG     ulongValue;
2456
2457   if (!check_string(user_name))
2458     {
2459       com_err(whoami, 0, "invalid LDAP user name %s", user_name);
2460       return(-1);
2461     }
2462
2463   group_count = 0;
2464   group_base = NULL;
2465   sprintf(filter_exp, "(sAMAccountName=%s)", user_name);
2466   attr_array[0] = "UserAccountControl";
2467   attr_array[1] = NULL;
2468   if ((rc = linklist_build(ldap_handle, dn_path, filter_exp, attr_array, 
2469                            &group_base, &group_count)) != 0)
2470     {
2471       com_err(whoami, 0, "LDAP server couldn't process user %s : %s",
2472               user_name, ldap_err2string(rc));
2473       return(rc);
2474     }
2475
2476   if (group_count != 1)
2477     {
2478       linklist_free(group_base);
2479       com_err(whoami, 0, "LDAP server unable to find user %s in AD",
2480               user_name);
2481       return(LDAP_NO_SUCH_OBJECT);
2482     }
2483
2484   strcpy(distinguished_name, group_base->dn);
2485   ulongValue = atoi((*group_base).value);
2486   if (operation == MEMBER_DEACTIVATE)
2487     ulongValue |= UF_ACCOUNTDISABLE;
2488   else    
2489     ulongValue &= ~UF_ACCOUNTDISABLE;
2490   sprintf(temp, "%ld", ulongValue);
2491   if ((rc = construct_newvalues(group_base, group_count, (*group_base).value, 
2492                                 temp, &modvalues, REPLACE)) == 1)
2493     goto cleanup;
2494   linklist_free(group_base);
2495   group_base = NULL;
2496   group_count = 0;
2497   n = 0;
2498   ADD_ATTR("UserAccountControl", modvalues, LDAP_MOD_REPLACE);
2499   mods[n] = NULL;
2500   rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
2501   for (i = 0; i < n; i++)
2502     free(mods[i]);
2503   free_values(modvalues);
2504   if (rc != LDAP_SUCCESS)
2505     {
2506       com_err(whoami, 0, "LDAP server could not change status of user %s : %s",
2507               user_name, ldap_err2string(rc));
2508     }
2509 cleanup:
2510   return(rc);
2511 }
2512
2513 int user_delete(LDAP *ldap_handle, char *dn_path, char *u_name)
2514 {
2515   char      filter_exp[1024];
2516   char      *attr_array[3];
2517   char      distinguished_name[1024];
2518   char      user_name[512];
2519   LK_ENTRY  *group_base;
2520   int       group_count;
2521   int       rc;
2522
2523   if (!check_string(u_name))
2524     return(0);
2525   strcpy(user_name, u_name);
2526   group_count = 0;
2527   group_base = NULL;
2528   sprintf(filter_exp, "(sAMAccountName=%s)", user_name);
2529   attr_array[0] = "name";
2530   attr_array[1] = NULL;
2531   if ((rc = linklist_build(ldap_handle, dn_path, filter_exp, attr_array, 
2532                            &group_base, &group_count)) != 0)
2533     {
2534       com_err(whoami, 0, "LDAP server couldn't process user %s : %s",
2535               user_name, ldap_err2string(rc));
2536       goto cleanup;
2537     }
2538
2539   if (group_count != 1)
2540     {
2541       com_err(whoami, 0, "LDAP server unable to find user %s in AD",
2542               user_name);
2543       goto cleanup;
2544     }
2545
2546   strcpy(distinguished_name, group_base->dn);
2547   if (rc = ldap_delete_s(ldap_handle, distinguished_name))
2548     {
2549       com_err(whoami, 0, "LDAP server couldn't process user %s : %s",
2550               user_name, ldap_err2string(rc));
2551     }
2552
2553 cleanup:
2554   linklist_free(group_base);
2555   return(0);
2556 }
2557
2558 void linklist_free(LK_ENTRY *linklist_base)
2559 {
2560   LK_ENTRY *linklist_previous;
2561
2562   while (linklist_base != NULL)
2563     {
2564       if (linklist_base->dn != NULL)
2565         free(linklist_base->dn);
2566       if (linklist_base->attribute != NULL)
2567         free(linklist_base->attribute);
2568       if (linklist_base->value != NULL)
2569         free(linklist_base->value);
2570       if (linklist_base->member != NULL)
2571         free(linklist_base->member);
2572       if (linklist_base->type != NULL)
2573         free(linklist_base->type);
2574       if (linklist_base->list != NULL)
2575         free(linklist_base->list);
2576       linklist_previous = linklist_base;
2577       linklist_base = linklist_previous->next;
2578       free(linklist_previous);
2579     }
2580 }
2581
2582 void free_values(char **modvalues)
2583 {
2584   int i;
2585
2586   i = 0;
2587   if (modvalues != NULL)
2588     {
2589     while (modvalues[i] != NULL)
2590       {
2591         free(modvalues[i]);
2592         modvalues[i] = NULL;
2593         ++i;
2594       }
2595     free(modvalues);
2596   }
2597 }
2598
2599 int sid_update(LDAP *ldap_handle, char *dn_path)
2600 {
2601   LK_ENTRY      *ptr;
2602   int           rc;
2603   unsigned char temp[126];
2604   char          *av[3];
2605
2606   ptr = sid_base;
2607
2608   while (ptr != NULL)
2609     {
2610       memset(temp, 0, sizeof(temp));
2611       convert_b_to_a(temp, ptr->value, ptr->length);
2612       if (!ptr->member)
2613         continue;
2614       av[0] = ptr->member;
2615       av[1] = temp;
2616       if (ptr->type == (char *)GROUPS)
2617         {
2618           ptr->type = NULL;
2619           rc = mr_query("add_list_sid_by_name", 2, av, NULL, NULL);
2620         }
2621       else if (ptr->type == (char *)USERS)
2622         {
2623           ptr->type = NULL;
2624           rc = mr_query("add_user_sid_by_login", 2, av, NULL, NULL);
2625         }
2626       ptr = ptr->next;
2627     }
2628   return(0);
2629 }
2630
2631 void convert_b_to_a(char *string, UCHAR *binary, int length)
2632 {
2633   int   i;
2634   int   j;
2635   UCHAR tmp;
2636
2637   j = 0;
2638   for (i = 0; i < length; i++)
2639     {
2640       tmp = binary[i];
2641       string[j] = tmp;
2642       string[j] >>= 4;
2643       string[j] &= 0x0f;
2644       string[j] += 0x30;
2645       if (string[j] > '9')
2646         string[j] += 0x27;
2647       ++j;
2648       string[j] = tmp & 0x0f;
2649       string[j] += 0x30;
2650       if (string[j] > '9')
2651         string[j] += 0x27;
2652       j++;
2653     }
2654   string[j] = 0;
2655 }
2656
2657 static int illegalchars[] = {
2658   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^@ - ^O */
2659   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^P - ^_ */
2660   1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, /* SPACE - / */
2661   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, /* 0 - ? */
2662   0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* @ - O */
2663   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, /* P - _ */
2664   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ` - o */
2665   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, /* p - ^? */
2666   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2667   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2668   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2669   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2670   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2671   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2672   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2673   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2674 };
2675
2676 int check_string(char *s)
2677 {
2678   char  character;
2679
2680   for (; *s; s++)
2681     {
2682       character = *s;
2683       if (isupper(character))
2684         character = tolower(character);
2685       if (illegalchars[(unsigned) character])
2686         return 0;
2687     }
2688   return 1;
2689 }
2690
2691 int mr_connect_cl(char *server, char *client, int version, int auth)
2692 {
2693   int   status;
2694   char  *motd;
2695   char  temp[128];
2696
2697   status = mr_connect(server);
2698   if (status)
2699     {
2700       com_err(whoami, status, "while connecting to Moira");
2701       return status;
2702     }
2703
2704   status = mr_motd(&motd);
2705   if (status)
2706     {
2707       mr_disconnect();
2708       com_err(whoami, status, "while checking server status");
2709       return status;
2710     }
2711   if (motd)
2712     {
2713       sprintf(temp, "The Moira server is currently unavailable: %s", motd);
2714       com_err(whoami, status, temp);
2715       mr_disconnect();
2716       return status;
2717     }
2718
2719   status = mr_version(version);
2720   if (status)
2721     {
2722       if (status == MR_UNKNOWN_PROC)
2723         {
2724           if (version > 2)
2725             status = MR_VERSION_HIGH;
2726           else
2727             status = MR_SUCCESS;
2728         }
2729
2730       if (status == MR_VERSION_HIGH)
2731         {
2732           com_err(whoami, 0, "Warning: This client is running newer code than the server.");
2733                   com_err(whoami, 0, "Some operations may not work.");
2734         }
2735       else if (status && status != MR_VERSION_LOW)
2736         {
2737           com_err(whoami, status, "while setting query version number.");
2738           mr_disconnect();
2739           return status;
2740         }
2741     }
2742
2743   if (auth)
2744     {
2745       status = mr_auth(client);
2746       if (status)
2747         {
2748           com_err(whoami, status, "while authenticating to Moira.");
2749           mr_disconnect();
2750           return status;
2751         }
2752     }
2753
2754   return MR_SUCCESS;
2755 }
2756
2757 void AfsToWinAfs(char* path, char* winPath)
2758 {
2759     char* pathPtr;
2760     char* winPathPtr;
2761     strcpy(winPath, WINAFS);
2762     pathPtr = path + strlen(AFS);
2763     winPathPtr = winPath + strlen(WINAFS);
2764
2765     while (*pathPtr)
2766     {
2767         if (*pathPtr == '/')
2768           *winPathPtr = '\\';
2769         else
2770           *winPathPtr = *pathPtr;
2771
2772         pathPtr++;
2773         winPathPtr++;
2774     }
2775 }
This page took 0.260984 seconds and 3 git commands to generate.