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