~ubuntu-branches/ubuntu/gutsy/directory-administrator/gutsy

« back to all changes in this revision

Viewing changes to src/appfunctions.c

  • Committer: Bazaar Package Importer
  • Author(s): Guido Trotter
  • Date: 2006-03-28 08:21:51 UTC
  • mfrom: (1.1.1 upstream) (2.1.1 hoary)
  • Revision ID: james.westby@ubuntu.com-20060328082151-y8h12be370r2exz1
Tags: 1.7.1-1
* The "On Train" release
* New upstream version
  - Doesn't violate object class rules anymore (closes: #195825)
* Forward port two debian patches which are still applicable
* Stop applying patches which seem not useful anymore
* Remove old "install" file

Show diffs side-by-side

added added

removed removed

Lines of Context:
10
10
   useful, but WITHOUT ANY WARRANTY; without even the implied warranty
11
11
   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
12
   GNU General Public License for more details.
13
 
 
14
 
   You should have received a copy of the GNU General Public License along
15
 
   with Directory administrator; if not, send e-mail to amador@alomega.com 
16
13
*/
17
14
 
18
 
 
19
15
#include <pthread.h>
20
16
#include "appsupport.h"
21
17
#include "appglobals.h"
23
19
#include "prefsdialog.h"
24
20
#include "appfunctions.h"
25
21
#include "dir_entry.h"
 
22
#include "schema.h"
26
23
 
27
24
GtkWidget *
28
25
create_messagebox_with_message (char *messagetext)
70
67
  g_print("\n\nget_user_uid_list: filtering entries for users' UIDs\n");
71
68
  for (it = g_list_first(cached_dir_entries);it;it=g_list_next(it))
72
69
    {
73
 
 
74
70
      if (dir_entry_is_user(it->data)) {
75
71
          milista =
76
72
            g_list_append (milista, g_strdup (dir_entry_get_uid(it->data)));
77
73
       }
78
 
 
79
 
 
80
74
    }
81
 
 
82
 
 
83
75
  milista = g_list_sort(milista,(GCompareFunc) g_strcasecmp);
84
76
  return milista;
85
 
 
86
77
}
 
78
 
87
79
GList *
88
80
get_group_cn_list_from_cache ()
89
81
{
93
85
  g_print("\n\nget_group_cn_list: filtering entries for groups' CNs\n");
94
86
  for (it = g_list_first(cached_dir_entries);it;it=g_list_next(it))
95
87
    {
96
 
 
97
88
      if (dir_entry_is_group(it->data)) {
98
 
 
99
89
          milista =
100
90
            g_list_append (milista, g_strdup (dir_entry_get_cn(it->data)));
101
91
       }
102
 
 
103
 
 
104
92
    }
105
93
  milista = g_list_sort(milista,(GCompareFunc) g_strcasecmp);
106
94
  return milista;
107
 
 
108
95
}
109
96
 
110
 
 
111
 
 
112
 
 
113
97
void
114
98
fill_users_dropdown (GtkWidget * dropdown)
115
99
{
190
174
                          results);
191
175
      if (entry)
192
176
        {
193
 
 
194
177
          while (entry)
195
178
            {
196
 
 
197
179
              value_collection = ldap_get_values (conn, entry, "uidnumber");
198
180
              g_assert (value_collection);
199
181
              milista =
230
212
 
231
213
          g_list_foreach (milista, (GFunc) g_free, NULL);
232
214
          g_list_free (milista);
233
 
 
234
215
        }
235
216
      else
236
217
        {
268
249
      return NULL;
269
250
    }
270
251
 
271
 
 
272
252
  filter = "(objectClass=posixGroup)";
273
253
 
274
254
  attributetoreturn[0] = "gidnumber";
290
270
          g_snprintf (lowestuid, 256, "%d",
291
271
                      preferences.logindefaults.VGID_MIN);
292
272
                ldap_msgfree (results);
293
 
 
294
273
        }
295
 
 
296
274
  else
297
 
    {
 
275
  {
298
276
      g_assert (results);
299
277
 
300
278
      entry =
301
279
        ldap_first_entry (connection_profile_get_ldap_handler (usethisone),
302
280
                          results);
303
281
 
304
 
      if (entry)
305
 
        {
 
282
   if (entry)
 
283
   {
306
284
          while (entry)
307
285
            {
308
 
 
309
286
              value_collection =
310
287
                ldap_get_values (connection_profile_get_ldap_handler
311
288
                                 (usethisone), entry, "gidnumber");
339
316
                      preferences.logindefaults.VGID_MIN);
340
317
        }
341
318
      ldap_msgfree (results);
342
 
 
343
319
    }
344
320
//  g_free(filter);  NOT FREED - STATIC!
345
321
  return (lowestuid);
346
 
 
347
322
}
348
323
 
349
324
GList *
355
330
  g_print("\n\nget_orgunit_dn_list: filtering entries for orgunits' DNs\n");
356
331
  for (it = g_list_first(cached_dir_entries);it;it=g_list_next(it))
357
332
    {
358
 
 
359
333
      if (dir_entry_is_orgunit(it->data)) {
360
 
 
361
334
          milista =
362
335
            g_list_append (milista, g_strdup (dir_entry_get_dn(it->data)));
363
336
       }
364
 
 
365
 
 
366
337
    }
367
338
  milista = g_list_sort(milista,(GCompareFunc) g_strcasecmp);
368
339
  return milista;
369
 
 
370
340
}
371
341
 
372
 
 
373
 
 
374
342
void open_website(void) {
375
343
  gchar **args = g_new0(gchar*,3);
376
344
  args[0] = "--newwin";
380
348
}
381
349
 
382
350
void app_set_status(gchar* message) {
383
 
 
384
351
  GnomeApp* a = (GnomeApp*)app;
385
352
  GnomeAppBar* b = (GnomeAppBar*)a->statusbar;
386
353
  gnome_appbar_set_status(b,message);
387
354
  while (g_main_iteration(FALSE)) {};
388
 
 
389
355
}
390
356
 
391
357
void app_set_progress(gfloat progress) {
392
 
 
393
358
  GnomeApp* a = (GnomeApp*)app;
394
359
  GnomeAppBar* b = (GnomeAppBar*)a->statusbar;
395
360
  GtkProgress* p = gnome_appbar_get_progress(b);
396
361
 
397
362
  gtk_progress_set_percentage(p,progress);
398
363
  while (g_main_iteration(FALSE)) {};
399
 
 
400
364
}
401
365
 
402
366
void app_interactive_connect(void) {
416
380
        }
417
381
      else if (g_list_length (connection_profile_list))
418
382
        {
419
 
//          g_print("Existen perfiles de conexion\n");
420
383
          about = create_connect_selectprofile ();
421
384
          gtk_widget_show (about);
422
385
        }
436
399
/*        gtk_widget_show (create_messagebox_with_message
437
400
                           ("Please create a new connection profile")); */
438
401
        }
439
 
 
440
 
 
441
 
 
442
402
}
443
403
 
444
 
 
445
404
void app_interactive_disconnect(void) {
446
405
//disconnects the application interactively
447
406
 
451
410
   connection_profile_destroy (current_connection_profile);
452
411
   current_connection_profile = NULL;
453
412
 
454
 
 
455
413
//turn off buttons
456
414
      gtk_widget_set_sensitive (lookup_widget
457
415
                                (GTK_WIDGET (togglebutton), "button_refresh"),
476
434
app_disable_editing_controls();
477
435
app_disable_filtercontrols();
478
436
 
479
 
 
480
 
 
481
437
      //this has the effect of emptying user lists
482
438
      app_refresh();
483
439
}
487
443
  if (connection_profile_is_connected(current_connection_profile)) return
488
444
TRUE;
489
445
  return FALSE;
490
 
 
491
446
}
492
447
 
493
448
int _app_connect(char *profilename) {
500
455
  g_assert (profilename);
501
456
  g_print ("\ncalled: app_connect with profile name: %s\n", profilename);
502
457
 
503
 
 
504
458
  ///DESTROY AND FREE THE ARGUMENT!!!!! SET IT TO NULL AFTER DESTROYING IT PLEAse
505
459
  //  BUGBUG should make sure it is disconnected first!!!!
506
460
 
529
483
  }
530
484
 
531
485
  if (ldap_error_definition)
532
 
 
533
486
    {
534
 
 
535
487
                if (ldap_error_definition != LDAP_INVALID_CREDENTIALS) {
536
488
                        if (ldap_error_definition == 91) {
537
489
                                if (connection_profile_get_tls(current_connection_profile)) {
569
521
      gtk_widget_set_sensitive (lookup_widget (app, "disconnect1"), TRUE);
570
522
          app_enable_filtercontrols();
571
523
  }
572
 
 
573
 
 
574
524
  return (ldap_error_definition);
575
 
 
576
525
}
577
526
 
578
527
int app_connect(char *profilename) {
579
 
 
580
528
  _app_connect(profilename);
581
529
  return 0;
582
 
 
583
530
}
584
531
 
585
 
 
586
532
void app_refresh(void) {
587
533
char buf[2048];
588
534
char *message;
595
541
 app_set_status("Analyzing data...");
596
542
 objectview_fill();
597
543
 
598
 
 
599
544
if (connection_profile_is_connected(current_connection_profile)) {
600
545
 
601
546
 numobjects = g_list_length(cached_dir_entries);
617
562
 gtk_window_set_title(GTK_WINDOW(app),"Directory administrator");
618
563
 }
619
564
 app_set_progress(0);
620
 
 
621
 
 
622
 
 
623
565
}
624
566
 
625
 
 
626
 
 
627
567
void _delete_this_user_from_this_group(gint gidnumber,char*dn,char*uid) {
628
568
        char*groupdn = NULL;
629
569
        dir_entry*groupentry = NULL;
667
607
        ldaptransaction_destroy(t);
668
608
        diradmin_group_destroy(oldgroup);
669
609
        diradmin_group_destroy(newgroup);
670
 
 
671
610
}
672
611
 
673
 
 
674
612
void _delete_this_dn_from_this_group(char*dn,gint gidnumber) {
675
613
        char*groupdn = NULL;
676
614
        dir_entry*groupentry = NULL;
712
650
        ldaptransaction_destroy(t);
713
651
        diradmin_group_destroy(oldgroup);
714
652
        diradmin_group_destroy(newgroup);
715
 
 
716
653
}
717
654
 
718
655
void _delete_this_uid_from_this_group(char*dn,gint gidnumber) {
756
693
        ldaptransaction_destroy(t);
757
694
        diradmin_group_destroy(oldgroup);
758
695
        diradmin_group_destroy(newgroup);
759
 
 
760
696
}
761
697
 
762
698
void _delete_this_user_from_all_groups(char*dn) {
769
705
        int ldap_errors;
770
706
        GList* currentelement;
771
707
 
772
 
 
773
708
        userentry = cached_dir_entries_getbydn(dn);
774
709
        if (userentry == NULL) return;
775
710
 
776
 
 
777
711
        for (currentelement=cached_dir_entries;currentelement;currentelement=currentelement->next)
778
712
        if (dir_entry_is_group(currentelement->data))
779
713
        {
808
742
                ldaptransaction_destroy(t);
809
743
                diradmin_group_destroy(oldgroup);
810
744
                diradmin_group_destroy(newgroup);
811
 
 
812
745
        }
813
746
}
814
747
 
815
 
 
816
748
void _add_this_dn_to_this_group(char*dn,gint gidnumber) {
817
749
        char*groupdn = NULL;
818
750
        dir_entry*groupentry = NULL;
820
752
        ldaptransaction*t;
821
753
        int ldap_errors;
822
754
 
823
 
 
824
755
        //g_print("\nAdding %s to group with gid number %d\n",dn,gidnumber);
825
756
        groupentry = cached_dir_entries_getgroupbygidnumber(gidnumber);
826
757
        if (groupentry == NULL) return;
851
782
        ldaptransaction_destroy(t);
852
783
        diradmin_group_destroy(oldgroup);
853
784
        diradmin_group_destroy(newgroup);
854
 
 
855
785
}
856
786
 
857
 
 
858
787
void _group_remove_memberuid(char*groupdn,char*uid) {
859
788
        diradmin_group * oldgroup;diradmin_group * newgroup;
860
789
        ldaptransaction*t;
890
819
        ldaptransaction_destroy(t);
891
820
        diradmin_group_destroy(oldgroup);
892
821
        diradmin_group_destroy(newgroup);
893
 
 
894
822
}
895
823
 
896
 
 
897
824
void _group_add_memberuid(char*groupdn,char*uid) {
898
825
        diradmin_group * oldgroup;diradmin_group * newgroup;
899
826
        ldaptransaction*t;
900
827
        int ldap_errors;
901
828
 
902
 
 
903
829
        //g_print("\nAdding %s to group with gid number %d\n",dn,gidnumber);
904
830
        g_print("\nAdding UID %s to group %s\n",uid,groupdn);
905
831
 
926
852
        ldaptransaction_destroy(t);
927
853
        diradmin_group_destroy(oldgroup);
928
854
        diradmin_group_destroy(newgroup);
929
 
 
930
855
}
931
856
 
932
857
void _group_switch_memberuids(char*groupdn,char*olduid,char*newuid) {
934
859
        ldaptransaction*t;
935
860
        int ldap_errors;
936
861
 
937
 
 
938
862
        //g_print("\nAdding %s to group with gid number %d\n",dn,gidnumber);
939
863
        g_print("\nSwitching UIDs from %s to %s in group %s\n",olduid,newuid,groupdn);
940
864
 
962
886
        ldaptransaction_destroy(t);
963
887
        diradmin_group_destroy(oldgroup);
964
888
        diradmin_group_destroy(newgroup);
965
 
 
966
889
}
967
890
 
968
891
void app_enable_filtercontrols (void) {
973
896
 gtk_widget_set_sensitive(lookup_widget(app,"filterclear"),TRUE);
974
897
 gtk_widget_set_sensitive(lookup_widget(app,"filteradvanced"),TRUE);
975
898
 app_filter_fill();
976
 
 
977
899
}
978
900
 
979
901
void app_disable_filtercontrols (void) {
984
906
 gtk_widget_set_sensitive(lookup_widget(app,"filterclear"),FALSE);
985
907
 gtk_widget_set_sensitive(lookup_widget(app,"filteradvanced"),FALSE);
986
908
 app_filter_fill();
987
 
 
988
909
}
989
910
 
990
911
void app_filter_fill (void )
991
912
{
992
 
 
993
913
  //gint i;
994
914
  GList * dnlist;
995
915
  GtkEntry*m;
1002
922
gtk_entry_set_text(m,"");
1003
923
}
1004
924
 
1005
 
 
1006
 
 
1007
925
int app_delete_interactive(GList *dns) {
1008
926
        LDAP *conn;
1009
927
        int ldap_errors = LDAP_SUCCESS;
1079
997
//    objectview_select_first();
1080
998
 
1081
999
//    objectview_remove_bydn (dn);
1082
 
 
1083
1000
}
1084
1001
 
1085
1002
void app_add_dir_entry (dir_entry* d) {
1089
1006
    dir_entry_dump(d);
1090
1007
    cached_dir_entries_add (d);
1091
1008
    objectview_fill ();
1092
 
 
1093
1009
}
1094
1010
 
1095
1011
void cached_dir_entries_add(dir_entry*d) {
1097
1013
cached_dir_entries = g_list_append(cached_dir_entries,d);
1098
1014
cached_dir_entries = g_list_sort(cached_dir_entries,(GCompareFunc)
1099
1015
                             dir_entry_compare);
1100
 
 
1101
1016
}
1102
1017
 
1103
1018
void cached_dir_entries_remove_bydn(char*dn) {
1105
1020
GList* a;
1106
1021
dir_entry* b;
1107
1022
 
1108
 
 
1109
1023
g_assert(dn);
1110
1024
 
1111
1025
//g_print("\nDeleting entry %s from directory cache\n",dn);
1122
1036
    break;
1123
1037
  }
1124
1038
}
1125
 
 
1126
1039
}
1127
1040
 
1128
1041
void cached_dir_entries_refetch(connection_profile* c) {
1138
1051
 
1139
1052
//g_print("\nThis was just brought in from the directory:");
1140
1053
//dir_entry_list_dump(cached_dir_entries);
1141
 
 
1142
1054
}
1143
1055
 
1144
 
 
1145
1056
void app_enable_editing_controls (void ) {
1146
1057
 
1147
1058
      gtk_widget_set_sensitive (lookup_widget
1157
1068
                                (GTK_WIDGET (app), "remove1"),
1158
1069
                                TRUE);
1159
1070
}
 
1071
 
1160
1072
void app_disable_editing_controls (void ) {
1161
1073
 
1162
1074
      gtk_widget_set_sensitive (lookup_widget
1199
1111
dir_entry* cached_dir_entries_getgroupbycn(gchar*cn){
1200
1112
  return dir_entry_list_getgroupbycn(cached_dir_entries,cn);
1201
1113
}
 
1114
 
 
1115
/**
 
1116
 * Get the list of samba domains from the ldap server.
 
1117
 *
 
1118
 * This function queries the LDAP server for all entries
 
1119
 * containing the sambaDomain objectclass, and returns
 
1120
 * a list of sambaDomainName values.
 
1121
 */
 
1122
GList *
 
1123
app_get_sambadomains_from_ldap (connection_profile * usethisone, gchar **warning)
 
1124
{
 
1125
  //conn should already be connected, or else undefined behaviour!!!
 
1126
 
 
1127
  int ldap_errors;
 
1128
 
 
1129
  GList *sambaDomains = NULL;
 
1130
 
 
1131
  LDAP *h;
 
1132
  LDAPMessage *searchresults = NULL;
 
1133
  LDAPMessage *entry = NULL;
 
1134
 
 
1135
  char **value_collection = NULL;
 
1136
 
 
1137
  gchar *attribute;
 
1138
  BerElement *attributehandler;
 
1139
  gchar *attributetoreturn[2];
 
1140
  attributetoreturn[0] = SAMBA_DOMAIN_NAME;
 
1141
  attributetoreturn[1] = NULL;
 
1142
 
 
1143
  g_print ("\no Fetching samba domains from directory with base %s\n", usethisone->treeroot);
 
1144
 
 
1145
  /* check for a connection */
 
1146
  h = connection_profile_get_ldap_handler (usethisone);
 
1147
  g_assert (h);
 
1148
 
 
1149
  /* look data up */
 
1150
  ldap_errors =
 
1151
    ldap_search_s (h, usethisone->treeroot, LDAP_SCOPE_SUBTREE, "(objectclass=" SAMBA_DOMAIN ")", attributetoreturn, 0,
 
1152
                   &searchresults);
 
1153
 
 
1154
  if (ldap_errors) {
 
1155
    warning[0] = g_strconcat("While searching for Samba domains, an LDAP error\noccurred: ", ldap_err2string (ldap_errors), NULL);
 
1156
    if (ldap_errors ==  LDAP_SERVER_DOWN) {
 
1157
      connection_profile_invalidate(usethisone);
 
1158
    }
 
1159
    return NULL;
 
1160
  }
 
1161
  else {
 
1162
    /* loop through any entries found */
 
1163
    entry = ldap_first_entry (h, searchresults);
 
1164
    while (entry) {
 
1165
      attribute = ldap_first_attribute (h, entry, &attributehandler);
 
1166
      value_collection = ldap_get_values (h, entry, attribute);
 
1167
      g_assert (value_collection);
 
1168
      sambaDomains = g_list_append (sambaDomains, g_strdup (value_collection[0]));
 
1169
      g_print ("  - Found samba domain: %s\n", value_collection[0]);
 
1170
      ldap_value_free (value_collection);
 
1171
      entry = ldap_next_entry (h, entry);
 
1172
    }
 
1173
    ldap_msgfree (searchresults);
 
1174
  }
 
1175
  return (sambaDomains);
 
1176
}
 
1177
 
 
1178
/**
 
1179
 * Get a list of possible well known windows domain groups.
 
1180
 *
 
1181
 */
 
1182
GList *
 
1183
app_get_sambagroupmappingdropdown ()
 
1184
{
 
1185
 
 
1186
  GList *sambaDomainMappings = NULL;
 
1187
 
 
1188
  sambaDomainMappings = g_list_append (sambaDomainMappings, g_strdup (DOMAIN_NONE));
 
1189
  sambaDomainMappings = g_list_append (sambaDomainMappings, g_strdup (DOMAIN_ADMINS));
 
1190
  sambaDomainMappings = g_list_append (sambaDomainMappings, g_strdup (DOMAIN_USERS));
 
1191
  sambaDomainMappings = g_list_append (sambaDomainMappings, g_strdup (DOMAIN_GUESTS));
 
1192
  sambaDomainMappings = g_list_append (sambaDomainMappings, g_strdup (DOMAIN_COMPUTERS));
 
1193
  sambaDomainMappings = g_list_append (sambaDomainMappings, g_strdup (DOMAIN_CONTROLLERS));
 
1194
  sambaDomainMappings = g_list_append (sambaDomainMappings, g_strdup (DOMAIN_CERTIFICATE_ADMINS));
 
1195
  sambaDomainMappings = g_list_append (sambaDomainMappings, g_strdup (DOMAIN_SCHEMA_ADMINS));
 
1196
  sambaDomainMappings = g_list_append (sambaDomainMappings, g_strdup (DOMAIN_ENTERPRISE_ADMINS));
 
1197
  sambaDomainMappings = g_list_append (sambaDomainMappings, g_strdup (DOMAIN_POLICY_ADMINS));
 
1198
 
 
1199
  return (sambaDomainMappings);
 
1200
 
 
1201
}
 
1202
 
 
1203
 
 
1204
/**
 
1205
 * If the provided group is a well known windows group, return the rid
 
1206
 * of that group, otherwise return zero.
 
1207
 */
 
1208
int app_get_sambaridfromgroupmapping (gchar *sambaDomainMapping) {
 
1209
 
 
1210
  int rid = 0;
 
1211
  
 
1212
  /* sanity check */
 
1213
  if (sambaDomainMapping == NULL) {
 
1214
    rid = 0;
 
1215
  }
 
1216
 
 
1217
  if (!strcmp(sambaDomainMapping, DOMAIN_ADMINS)) {
 
1218
    rid = DOMAIN_ADMINS_RID;
 
1219
  }
 
1220
  if (!strcmp(sambaDomainMapping, DOMAIN_USERS)) {
 
1221
    rid = DOMAIN_USERS_RID;
 
1222
  }
 
1223
  if (!strcmp(sambaDomainMapping, DOMAIN_GUESTS)) {
 
1224
    rid = DOMAIN_GUESTS_RID;
 
1225
  }
 
1226
  if (!strcmp(sambaDomainMapping, DOMAIN_COMPUTERS)) {
 
1227
    rid = DOMAIN_COMPUTERS_RID;
 
1228
  }
 
1229
  if (!strcmp(sambaDomainMapping, DOMAIN_CONTROLLERS)) {
 
1230
    rid = DOMAIN_CONTROLLERS_RID;
 
1231
  }
 
1232
  if (!strcmp(sambaDomainMapping, DOMAIN_CERTIFICATE_ADMINS)) {
 
1233
    rid = DOMAIN_CERTIFICATE_ADMINS_RID;
 
1234
  }
 
1235
  if (!strcmp(sambaDomainMapping, DOMAIN_SCHEMA_ADMINS)) {
 
1236
    rid = DOMAIN_SCHEMA_ADMINS_RID;
 
1237
  }
 
1238
  if (!strcmp(sambaDomainMapping, DOMAIN_POLICY_ADMINS)) {
 
1239
    rid = DOMAIN_POLICY_ADMINS_RID;
 
1240
  }
 
1241
 
 
1242
  return rid;
 
1243
  
 
1244
}
 
1245
 
 
1246
 
 
1247
/**
 
1248
 * From the SID of the group, return the well known group it corresponds
 
1249
 * to. If the SID is not identified as a well known group, then return
 
1250
 * the empty string.
 
1251
 */
 
1252
gchar * app_get_sambagroupmappingfromsid (gchar *sid) {
 
1253
 
 
1254
  int rid = 0;
 
1255
  
 
1256
  /* sanity check */
 
1257
  if (sid == NULL) {
 
1258
    return (g_strdup(DOMAIN_NONE));
 
1259
  }
 
1260
 
 
1261
  /* get the rid from the SID */
 
1262
  int i = 0;
 
1263
  for (i = strlen(sid); i > 0; i--) {
 
1264
    if (sid[i] == '-') {
 
1265
      break;
 
1266
    }
 
1267
  }
 
1268
  rid = - atoi(sid + i);
 
1269
  
 
1270
  switch (rid) {
 
1271
    case DOMAIN_ADMINS_RID: return DOMAIN_ADMINS;
 
1272
    case DOMAIN_USERS_RID: return DOMAIN_USERS;
 
1273
    case DOMAIN_GUESTS_RID: return DOMAIN_GUESTS;
 
1274
    case DOMAIN_COMPUTERS_RID: return DOMAIN_COMPUTERS;
 
1275
    case DOMAIN_CONTROLLERS_RID: return DOMAIN_CONTROLLERS;
 
1276
    case DOMAIN_CERTIFICATE_ADMINS_RID: return DOMAIN_CERTIFICATE_ADMINS;
 
1277
    case DOMAIN_SCHEMA_ADMINS_RID: return DOMAIN_SCHEMA_ADMINS;
 
1278
    case DOMAIN_POLICY_ADMINS_RID: return DOMAIN_POLICY_ADMINS;
 
1279
  }
 
1280
 
 
1281
  return DOMAIN_NONE;
 
1282
 
 
1283
}
 
1284
 
 
1285
 
 
1286
/**
 
1287
 * Calculate the sambaSID attribute
 
1288
 *
 
1289
 * This function queries the LDAP server for the given
 
1290
 * sambaDomain objectclass specified by the sambaDomainName
 
1291
 * provided.
 
1292
 *
 
1293
 * If the specified rid is zero, the given uid is multiplied by
 
1294
 * two and is added to the value of sambaAlgorithmicRidBase, which in
 
1295
 * turn is tacked onto the end of sambaSID, giving the resulting value
 
1296
 * for sambaSID for this object.
 
1297
 *
 
1298
 * If group is given the value "1", then one will be added to the uid
 
1299
 * to make it a group id. Group ids are odd numbers.
 
1300
 */
 
1301
gchar *
 
1302
app_get_sambasid_from_ldap (connection_profile * usethisone, gchar *sambaDomain, int rid, gchar *uidnumber, int group, gchar **warning)
 
1303
{
 
1304
  //conn should already be connected, or else undefined behaviour!!!
 
1305
 
 
1306
  int ldap_errors;
 
1307
 
 
1308
  LDAP *h;
 
1309
  LDAPMessage *searchresults = NULL;
 
1310
  LDAPMessage *entry = NULL;
 
1311
 
 
1312
  char **value_collection = NULL;
 
1313
 
 
1314
  gchar *attribute;
 
1315
  gchar *filter;
 
1316
  gchar *sambaAlgorithmicRidBase = NULL;
 
1317
  gchar *sambaSID = NULL;
 
1318
  gchar *userSambaSID = NULL;
 
1319
  char buffer[11];
 
1320
  BerElement *attributehandler;
 
1321
  gchar *attributetoreturn[3];
 
1322
  attributetoreturn[0] = SAMBA_ALGORITHMIC_RID_BASE;
 
1323
  attributetoreturn[1] = SAMBA_SID;
 
1324
  attributetoreturn[2] = NULL;
 
1325
 
 
1326
  filter = g_strconcat ("(&(objectclass=" SAMBA_DOMAIN ")(" SAMBA_DOMAIN_NAME "=", sambaDomain, "))", NULL);
 
1327
  g_print ("\no Fetching sambaDomain %s from directory with base\n  \"%s\" using filter:\n  \"%s\"\n\n", sambaDomain, usethisone->treeroot, filter);
 
1328
 
 
1329
  /* check for a connection */
 
1330
  h = connection_profile_get_ldap_handler (usethisone);
 
1331
  g_assert (h);
 
1332
 
 
1333
  /* look data up */
 
1334
  ldap_errors =
 
1335
    ldap_search_s (h, usethisone->treeroot, LDAP_SCOPE_SUBTREE, filter, attributetoreturn, 0,
 
1336
                   &searchresults);
 
1337
 
 
1338
  if (ldap_errors) {
 
1339
    warning[0] = g_strconcat("While searching for Samba domain '", sambaDomain, "',\nan LDAP error occurred: ", ldap_err2string (ldap_errors), NULL);
 
1340
    if (ldap_errors ==  LDAP_SERVER_DOWN) {
 
1341
      connection_profile_invalidate(usethisone);
 
1342
    }
 
1343
    return NULL;
 
1344
  }
 
1345
  else {
 
1346
    /* loop through any entries found, extract attributes */
 
1347
    entry = ldap_first_entry (h, searchresults);
 
1348
    while (entry) {
 
1349
      attribute = ldap_first_attribute (h, entry, &attributehandler);
 
1350
      while (attribute) {
 
1351
        value_collection = ldap_get_values (h, entry, attribute);
 
1352
        g_assert (value_collection);
 
1353
        g_print ("  - Processing: %s\n", attribute);
 
1354
        if (g_strcasecmp (attribute, SAMBA_ALGORITHMIC_RID_BASE) == 0) {
 
1355
          sambaAlgorithmicRidBase = g_strdup(value_collection[0]);
 
1356
          g_print ("  - Found sambaAlgorithmicRidBase: %s\n", sambaAlgorithmicRidBase);
 
1357
        }
 
1358
        else if (g_strcasecmp (attribute, SAMBA_SID) == 0) {
 
1359
          sambaSID = g_strdup(value_collection[0]);
 
1360
          g_print ("  - Found sambaSID: %s\n", sambaSID);
 
1361
        }
 
1362
        ldap_value_free (value_collection);
 
1363
        attribute = ldap_next_attribute (h, entry, attributehandler);
 
1364
      }
 
1365
      entry = ldap_next_entry (h, entry);
 
1366
    }
 
1367
 
 
1368
    ldap_msgfree (searchresults);
 
1369
  }
 
1370
 
 
1371
  /* sanity check */
 
1372
  if (!sambaSID) {
 
1373
    warning[0] = g_strconcat("A Samba domain '", sambaDomain, "' was found, but this object has\nno sambaSID attribute associated with it.\n", NULL);
 
1374
    g_print ("  - %s\n", *warning);
 
1375
    return NULL;
 
1376
  }
 
1377
  if (!sambaAlgorithmicRidBase) {
 
1378
    warning[0] = g_strconcat("A Samba domain '", sambaDomain, "' was found, but this object has\nno sambaAlgorithmicRidBase attribute associated with it.\n", NULL);
 
1379
    g_print ("  - %s\n", *warning);
 
1380
    return NULL;
 
1381
  }
 
1382
 
 
1383
  /* create sambaSID of user or group */
 
1384
  sprintf(buffer, "%d", rid > 0 ? rid : (2*atoi(uidnumber) + atoi(sambaAlgorithmicRidBase) + group));
 
1385
  userSambaSID = g_strconcat(sambaSID, "-", buffer, NULL);
 
1386
  g_free(sambaSID);
 
1387
  g_free(sambaAlgorithmicRidBase);
 
1388
  g_print ("  - Returned SID %s\n", userSambaSID);
 
1389
  return userSambaSID;
 
1390
}
 
1391
 
 
1392
/**
 
1393
 * Get the domain by sambaSID
 
1394
 *
 
1395
 * This function queries the LDAP server for the given
 
1396
 * sambaDomain objectclass specified by the sambaSID
 
1397
 * provided.
 
1398
 *
 
1399
 * The sambaSID is first stripped of the userid component, then a
 
1400
 * search is conducted of the LDAP server for the name of the domain
 
1401
 * corresponding to the given SID.
 
1402
 *
 
1403
 * If no domain is found, NULL is returned.
 
1404
 */
 
1405
gchar *
 
1406
app_get_sambadomain_by_sambasid_from_ldap (connection_profile * usethisone, gchar *sid, gchar **warning)
 
1407
{
 
1408
  //conn should already be connected, or else undefined behaviour!!!
 
1409
 
 
1410
  int ldap_errors;
 
1411
 
 
1412
  LDAP *h;
 
1413
  LDAPMessage *searchresults = NULL;
 
1414
  LDAPMessage *entry = NULL;
 
1415
 
 
1416
  char **value_collection = NULL;
 
1417
 
 
1418
  gchar *attribute;
 
1419
  gchar *filter;
 
1420
  gchar *sambaDomainName = NULL;
 
1421
  BerElement *attributehandler;
 
1422
  gchar *attributetoreturn[2];
 
1423
  attributetoreturn[0] = SAMBA_DOMAIN_NAME;
 
1424
  attributetoreturn[1] = NULL;
 
1425
  int i;
 
1426
  
 
1427
  gchar *sambaSID;
 
1428
 
 
1429
  /* sanity check */
 
1430
  if (sid == NULL) {
 
1431
    return NULL;
 
1432
  }
 
1433
 
 
1434
  /* first, strip off the end of the SID */
 
1435
  sambaSID = g_strdup(sid);
 
1436
  i = strlen(sambaSID);
 
1437
  while (i-- > 0) {
 
1438
    if (sambaSID[i] == '-') {
 
1439
      sambaSID[i] = 0;
 
1440
      break;
 
1441
    }
 
1442
  }
 
1443
 
 
1444
  /* now, search for the domain corresponding to the sambaSID */
 
1445
  filter = g_strconcat ("(&(objectclass=" SAMBA_DOMAIN ")(" SAMBA_SID "=", sambaSID, "))", NULL);
 
1446
  g_print ("\no Fetching sambaDomain with sambaSID %s\n  from directory with base %s using filter:\n  %s\n\n", sid, usethisone->treeroot, filter);
 
1447
 
 
1448
 
 
1449
  /* check for a connection */
 
1450
  h = connection_profile_get_ldap_handler (usethisone);
 
1451
  g_assert (h);
 
1452
 
 
1453
  /* look data up */
 
1454
  ldap_errors =
 
1455
    ldap_search_s (h, usethisone->treeroot, LDAP_SCOPE_SUBTREE, filter, attributetoreturn, 0,
 
1456
                   &searchresults);
 
1457
 
 
1458
  g_free(sambaSID);
 
1459
  g_free(filter);
 
1460
 
 
1461
  if (ldap_errors) {
 
1462
    warning[0] = g_strconcat("While searching for domains matching the sambaSID '", sid, "',\nan LDAP error occurred: ", ldap_err2string (ldap_errors), NULL);
 
1463
    if (ldap_errors ==  LDAP_SERVER_DOWN) {
 
1464
      connection_profile_invalidate(usethisone);
 
1465
    }
 
1466
    return NULL;
 
1467
  }
 
1468
  else {
 
1469
      /* only consider the first entry */
 
1470
      entry = ldap_first_entry (h, searchresults);
 
1471
      if (!entry) {
 
1472
        warning[0] = g_strconcat("While searching for domains matching the sambaSID '", sid, "',\nno domains were found. This is probably caused by your domain object not being accessible beneath\n", usethisone->treeroot, ". Please fix your Windows domain configuration.", NULL);
 
1473
        ldap_msgfree (searchresults);
 
1474
        return NULL;
 
1475
      }
 
1476
 
 
1477
      /* find the attribute we were looking for */      
 
1478
      attribute = ldap_first_attribute (h, entry, &attributehandler);
 
1479
      if (!attribute) {
 
1480
        warning[0] = g_strconcat("While searching for domains matching the sambaSID '", sid, "',\nthe domain was found, but it did not contain the attribute ", SAMBA_DOMAIN_NAME, ".\nPlease fix your Windows domain configuration.", NULL);
 
1481
        ldap_msgfree (searchresults);
 
1482
        return NULL;
 
1483
      }
 
1484
      
 
1485
      value_collection = ldap_get_values (h, entry, attribute);
 
1486
      g_assert (value_collection);
 
1487
      sambaDomainName = g_strdup (value_collection[0]);
 
1488
      g_print ("  - Samba domain found: %s\n", value_collection[0]);
 
1489
      ldap_value_free (value_collection);
 
1490
 
 
1491
      /* any further entries is a sign of trouble */
 
1492
      if (ldap_next_entry (h, searchresults)) {
 
1493
        warning[0] = g_strconcat("While searching for domains matching the sambaSID '", sid, "',\nmore than one domain was found. This is probably caused by a misconfiguration\nof your Samba domain within your LDAP server.", NULL);
 
1494
      }
 
1495
 
 
1496
      ldap_msgfree (searchresults);
 
1497
  }
 
1498
 
 
1499
  return sambaDomainName;
 
1500
}
 
1501
 
 
1502
 
 
1503
/**
 
1504
 * Pretty printing for LDAP errors
 
1505
 *
 
1506
 * This function pops up a warning dialog box, based on the errors
 
1507
 * returned by the LDAP server, if any.
 
1508
 */
 
1509
void app_handle_ldap_error(int rc, gchar **warning) {
 
1510
  char *message = NULL;
 
1511
  
 
1512
  switch (rc) {
 
1513
    case LDAP_SUCCESS: break;
 
1514
    case LDAP_OBJECT_CLASS_VIOLATION: {
 
1515
      message = "A required field is empty, has invalid characters, or your directory does not\nsupport a required object class. Please complete missing fields, correct invalid\ncharacters and check if your directory has support for needed object classes.";
 
1516
      break;
 
1517
    }
 
1518
    case LDAP_NO_SUCH_OBJECT: {
 
1519
      message = "Your directory seems to be empty.  Directory administrator requires a directory\nwith at least one group and one organizational unit. Visit PADL.com and look for\nthe MigrationTools which will help you populate your directory server.";
 
1520
      break;
 
1521
    }
 
1522
    case LDAP_INVALID_SYNTAX: {
 
1523
      message = "You specified invalid characters in one of the entry boxes (such as letters\nwhere only numbers are accepted). Please go back and correct errors.";
 
1524
      break;
 
1525
    }
 
1526
    case LDAP_UNDEFINED_TYPE: {
 
1527
      message = "Your directory server appears not to support a required object class.  Please tweak\ncompatibility options in Settings->Preferences or disable object class checking.";
 
1528
      break;
 
1529
    }
 
1530
    case LDAP_PROTOCOL_ERROR: {
 
1531
      message = "Your directory server appears not to support the current operation. If you were\ntrying to set a password, it could be due to your server not supporting the\nLDAP_EXOP_MODIFY_PASSWD extended operation. Please tweak compatibility\noptions in Settings->Preferences->When changing passwords.";
 
1532
      break;
 
1533
    }
 
1534
    default: {
 
1535
      message = ldap_err2string (rc);
 
1536
      break;
 
1537
    }
 
1538
  }
 
1539
 
 
1540
  if (message || (warning && *warning)) {
 
1541
    gtk_widget_show (create_messagebox_with_message (g_strconcat(warning && *warning ? *warning : "", warning && *warning ? "\n" : "", message ? message : "", NULL)));
 
1542
  }
 
1543
 
 
1544
  if (warning) {
 
1545
    *warning = NULL;
 
1546
  }
 
1547
}