Correctly free buffers in netdomjoin-gui.
[Samba/gebeck_regimport.git] / source / lib / netapi / examples / netdomjoin-gui / netdomjoin-gui.c
blob4a3588e9abae1dddf959a1e1fd82d035adcfdb91
1 /*
2 * Unix SMB/CIFS implementation.
3 * Join Support (gtk + netapi)
4 * Copyright (C) Guenther Deschner 2007-2008
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
20 #define _GNU_SOURCE
21 #include <stdio.h>
22 #include <sys/types.h>
23 #include <inttypes.h>
24 #include <stdlib.h>
25 #include <unistd.h>
26 #include <string.h>
28 #include <gtk/gtk.h>
29 #include <glib/gprintf.h>
31 #include <netapi.h>
33 #define MAX_CRED_LEN 256
34 #define MAX_NETBIOS_NAME_LEN 15
36 #define SAMBA_ICON_PATH "/usr/share/pixmaps/samba/samba.ico"
37 #define SAMBA_IMAGE_PATH "/usr/share/pixmaps/samba/logo.png"
38 #define SAMBA_IMAGE_PATH_SMALL "/usr/share/pixmaps/samba/logo-small.png"
40 #define WKSSVC_JOIN_FLAGS_DOMAIN_JOIN_IF_JOINED ( 0x00000020 )
41 #define WKSSVC_JOIN_FLAGS_ACCOUNT_DELETE ( 0x00000004 )
42 #define WKSSVC_JOIN_FLAGS_ACCOUNT_CREATE ( 0x00000002 )
43 #define WKSSVC_JOIN_FLAGS_JOIN_TYPE ( 0x00000001 )
45 #define NetSetupWorkgroupName ( 2 )
46 #define NetSetupDomainName ( 3 )
48 #define SAFE_FREE(x) do { if ((x) != NULL) {free(x); x=NULL;} } while(0)
50 struct srvsvc_NetSrvInfo1005 {
51 const char *comment;/* [unique,charset(UTF16)] */
54 static gboolean verbose = FALSE;
56 typedef struct join_state {
57 struct libnetapi_ctx *ctx;
58 GtkWidget *window_main;
59 GtkWidget *window_parent;
60 GtkWidget *window_do_change;
61 GtkWidget *window_creds_prompt;
62 GtkWidget *entry_account;
63 GtkWidget *entry_password;
64 GtkWidget *entry_domain;
65 GtkWidget *entry_workgroup;
66 GtkWidget *button_ok;
67 GtkWidget *button_apply;
68 GtkWidget *button_ok_creds;
69 GtkWidget *label_reboot;
70 GtkWidget *label_current_name_buffer;
71 GtkWidget *label_current_name_type;
72 GtkWidget *label_full_computer_name;
73 uint16_t name_type_initial;
74 uint16_t name_type_new;
75 char *name_buffer_initial;
76 char *name_buffer_new;
77 char *password;
78 char *account;
79 char *comment;
80 char *comment_new;
81 char *my_fqdn;
82 char *my_dnsdomain;
83 char *my_hostname;
84 uint16_t server_role;
85 gboolean settings_changed;
86 gboolean hostname_changed;
87 } join_state;
89 static void debug(const char *format, ...)
91 va_list args;
93 if (!verbose) {
94 return;
97 va_start(args, format);
98 g_vprintf(format, args);
99 va_end(args);
102 static gboolean callback_delete_event(GtkWidget *widget,
103 GdkEvent *event,
104 gpointer data)
106 gtk_main_quit();
107 return FALSE;
110 static void callback_do_close(GtkWidget *widget,
111 gpointer data)
113 debug("Closing now...\n");
114 gtk_widget_destroy(data);
117 static void free_join_state(struct join_state *s)
119 SAFE_FREE(s->name_buffer_initial);
120 SAFE_FREE(s->name_buffer_new);
121 SAFE_FREE(s->password);
122 SAFE_FREE(s->account);
123 SAFE_FREE(s->comment);
124 SAFE_FREE(s->comment_new);
125 SAFE_FREE(s->my_fqdn);
126 SAFE_FREE(s->my_dnsdomain);
127 SAFE_FREE(s->my_hostname);
130 static void do_cleanup(struct join_state *state)
132 libnetapi_free(state->ctx);
133 free_join_state(state);
136 static void callback_apply_description_change(GtkWidget *widget,
137 gpointer data)
139 struct join_state *state = (struct join_state *)data;
140 NET_API_STATUS status = 0;
141 uint32_t parm_err = 0;
142 struct srvsvc_NetSrvInfo1005 info1005;
143 GtkWidget *dialog;
145 info1005.comment = state->comment_new;
147 status = NetServerSetInfo(NULL, 1005, (uint8_t *)&info1005, &parm_err);
148 if (status) {
149 debug("NetServerSetInfo failed with: %s\n",
150 libnetapi_errstr(state->ctx, status));
151 dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_main),
152 GTK_DIALOG_DESTROY_WITH_PARENT,
153 GTK_MESSAGE_ERROR,
154 GTK_BUTTONS_OK,
155 "Failed to change computer description: %s.",
156 libnetapi_errstr(state->ctx, status));
157 g_signal_connect_swapped(dialog, "response",
158 G_CALLBACK(gtk_widget_destroy),
159 dialog);
161 gtk_widget_show(dialog);
162 return;
165 gtk_widget_set_sensitive(GTK_WIDGET(state->button_apply), FALSE);
168 static void callback_do_exit(GtkWidget *widget,
169 gpointer data)
171 GtkWidget *dialog;
172 gint result;
173 struct join_state *state = (struct join_state *)data;
175 if (!state->settings_changed) {
176 callback_delete_event(NULL, NULL, NULL);
177 return;
180 dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_main),
181 GTK_DIALOG_DESTROY_WITH_PARENT,
182 GTK_MESSAGE_QUESTION,
183 GTK_BUTTONS_YES_NO,
184 "You must restart your computer before the new settings will take effect.");
185 result = gtk_dialog_run(GTK_DIALOG(dialog));
186 switch (result) {
187 case GTK_RESPONSE_YES:
188 g_print("would reboot here\n");
189 break;
190 case GTK_RESPONSE_NO:
191 default:
192 break;
194 gtk_widget_destroy(dialog);
195 gtk_widget_destroy(state->window_main);
196 do_cleanup(state);
197 exit(0);
201 static void callback_do_reboot(GtkWidget *widget,
202 gpointer data,
203 gpointer data2)
205 GtkWidget *dialog;
206 struct join_state *state = (struct join_state *)data2;
208 debug("callback_do_reboot\n");
210 state->settings_changed = TRUE;
211 dialog = gtk_message_dialog_new(GTK_WINDOW(data),
212 GTK_DIALOG_DESTROY_WITH_PARENT,
213 GTK_MESSAGE_INFO,
214 GTK_BUTTONS_OK,
215 "You must restart this computer for the changes to take effect.");
216 #if 0
217 g_signal_connect_swapped(dialog, "response",
218 G_CALLBACK(gtk_widget_destroy),
219 dialog);
221 debug("showing dialog\n");
222 gtk_widget_show(dialog);
223 #else
224 gtk_dialog_run(GTK_DIALOG(dialog));
225 gtk_widget_destroy(dialog);
226 #endif
228 gtk_label_set_text(GTK_LABEL(state->label_reboot),
229 "Changes will take effect after you restart this computer");
231 debug("destroying do_change window\n");
232 gtk_widget_destroy(GTK_WIDGET(state->window_do_change));
235 uint32_t status;
236 const char *buffer;
237 uint16_t type;
239 status = NetGetJoinInformation(NULL, &buffer, &type);
240 if (status != 0) {
241 g_print("failed to query status\n");
242 return;
245 debug("got new status: %s\n", buffer);
246 #if 0
247 SAFE_FREE(state->name_buffer_new);
248 state->name_buffer_new = strdup(buffer);
249 SAFE_FREE(buffer);
250 state->name_type_new = type;
251 #endif
252 NetApiBufferFree((void *)buffer);
254 gtk_label_set_text(GTK_LABEL(state->label_current_name_buffer),
255 state->name_buffer_new);
256 if (state->name_type_new == NetSetupDomainName) {
257 gtk_label_set_text(GTK_LABEL(state->label_current_name_type),
258 "Domain:");
259 } else {
260 gtk_label_set_text(GTK_LABEL(state->label_current_name_type),
261 "Workgroup:");
266 static void callback_return_username(GtkWidget *widget,
267 gpointer data)
269 const gchar *entry_text;
270 struct join_state *state = (struct join_state *)data;
271 if (!widget) {
272 return;
274 entry_text = gtk_entry_get_text(GTK_ENTRY(widget));
275 debug("callback_return_username: %s\n", entry_text);
276 SAFE_FREE(state->account);
277 state->account = strdup(entry_text);
280 static void callback_return_username_and_enter(GtkWidget *widget,
281 gpointer data)
283 const gchar *entry_text;
284 struct join_state *state = (struct join_state *)data;
285 if (!widget) {
286 return;
288 entry_text = gtk_entry_get_text(GTK_ENTRY(widget));
289 debug("callback_return_username: %s\n", entry_text);
290 SAFE_FREE(state->account);
291 state->account = strdup(entry_text);
292 g_signal_emit_by_name(state->button_ok_creds, "clicked");
295 static void callback_return_password(GtkWidget *widget,
296 gpointer data)
298 const gchar *entry_text;
299 struct join_state *state = (struct join_state *)data;
300 if (!widget) {
301 return;
303 entry_text = gtk_entry_get_text(GTK_ENTRY(widget));
304 #ifdef DEBUG_PASSWORD
305 debug("callback_return_password: %s\n", entry_text);
306 #else
307 debug("callback_return_password: (not printed)\n");
308 #endif
309 SAFE_FREE(state->password);
310 state->password = strdup(entry_text);
313 static void callback_return_password_and_enter(GtkWidget *widget,
314 gpointer data)
316 const gchar *entry_text;
317 struct join_state *state = (struct join_state *)data;
318 if (!widget) {
319 return;
321 entry_text = gtk_entry_get_text(GTK_ENTRY(widget));
322 #ifdef DEBUG_PASSWORD
323 debug("callback_return_password: %s\n", entry_text);
324 #else
325 debug("callback_return_password: (not printed)\n");
326 #endif
327 SAFE_FREE(state->password);
328 state->password = strdup(entry_text);
329 g_signal_emit_by_name(state->button_ok_creds, "clicked");
332 static void callback_do_hostname_change(GtkWidget *widget,
333 gpointer data)
335 GtkWidget *dialog;
336 const char *str = NULL;
338 struct join_state *state = (struct join_state *)data;
340 switch (state->name_type_initial) {
341 case NetSetupDomainName:
342 str = "To be implemented: call NetRenameMachineInDomain\n";
343 break;
344 case NetSetupWorkgroupName:
345 str = "To be implemented: call SetComputerNameEx\n";
346 break;
347 default:
348 break;
351 dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_parent),
352 GTK_DIALOG_DESTROY_WITH_PARENT,
353 GTK_MESSAGE_ERROR,
354 GTK_BUTTONS_CLOSE,
355 str);
357 g_signal_connect_swapped(dialog, "response",
358 G_CALLBACK(gtk_widget_destroy),
359 dialog);
360 gtk_widget_show(dialog);
363 static void callback_do_join(GtkWidget *widget,
364 gpointer data)
366 GtkWidget *dialog;
368 NET_API_STATUS status;
369 const char *err_str = NULL;
370 uint32_t join_flags = 0;
371 uint32_t unjoin_flags = 0;
372 gboolean domain_join = FALSE;
373 gboolean try_unjoin = FALSE;
374 const char *new_workgroup_type = NULL;
375 const char *initial_workgroup_type = NULL;
377 struct join_state *state = (struct join_state *)data;
379 callback_return_username(state->entry_account, state);
380 callback_return_password(state->entry_password, state);
382 if (state->window_creds_prompt) {
383 gtk_widget_destroy(GTK_WIDGET(state->window_creds_prompt));
386 switch (state->name_type_initial) {
387 case NetSetupWorkgroupName:
388 initial_workgroup_type = "workgroup";
389 break;
390 case NetSetupDomainName:
391 initial_workgroup_type = "domain";
392 break;
393 default:
394 break;
397 switch (state->name_type_new) {
398 case NetSetupWorkgroupName:
399 new_workgroup_type = "workgroup";
400 break;
401 case NetSetupDomainName:
402 new_workgroup_type = "domain";
403 break;
404 default:
405 break;
408 if (state->name_type_new == NetSetupDomainName) {
409 domain_join = TRUE;
410 join_flags = WKSSVC_JOIN_FLAGS_JOIN_TYPE |
411 WKSSVC_JOIN_FLAGS_ACCOUNT_CREATE |
412 WKSSVC_JOIN_FLAGS_DOMAIN_JOIN_IF_JOINED; /* for testing */
415 if ((state->name_type_initial == NetSetupDomainName) &&
416 (state->name_type_new == NetSetupWorkgroupName)) {
417 try_unjoin = TRUE;
418 unjoin_flags = WKSSVC_JOIN_FLAGS_JOIN_TYPE |
419 WKSSVC_JOIN_FLAGS_ACCOUNT_DELETE;
422 debug("callback_do_join: Joining a %s named %s using join_flags 0x%08x ",
423 new_workgroup_type,
424 state->name_buffer_new,
425 join_flags);
426 if (domain_join) {
427 debug("as %s ", state->account);
428 #ifdef DEBUG_PASSWORD
429 debug("with %s ", state->password);
430 #endif
432 debug("\n");
433 if (try_unjoin) {
435 debug("callback_do_join: Unjoining\n");
437 status = NetUnjoinDomain(NULL,
438 state->account,
439 state->password,
440 unjoin_flags);
441 if (status != 0) {
442 err_str = libnetapi_errstr(state->ctx, status);
443 g_print("callback_do_join: failed to unjoin (%s)\n",
444 err_str);
446 dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_parent),
447 GTK_DIALOG_DESTROY_WITH_PARENT,
448 GTK_MESSAGE_ERROR,
449 GTK_BUTTONS_CLOSE,
450 "The following error occured attempting to unjoin the %s: \"%s\": %s",
451 initial_workgroup_type,
452 state->name_buffer_initial,
453 err_str);
454 gtk_dialog_run(GTK_DIALOG(dialog));
455 gtk_widget_destroy(dialog);
459 status = NetJoinDomain(NULL,
460 state->name_buffer_new,
461 NULL,
462 state->account,
463 state->password,
464 join_flags);
465 if (status != 0) {
466 err_str = libnetapi_errstr(state->ctx, status);
467 g_print("callback_do_join: failed to join (%s)\n", err_str);
469 dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_parent),
470 GTK_DIALOG_DESTROY_WITH_PARENT,
471 GTK_MESSAGE_ERROR,
472 GTK_BUTTONS_CLOSE,
473 "The following error occured attempting to join the %s: \"%s\": %s",
474 new_workgroup_type,
475 state->name_buffer_new,
476 err_str);
478 g_signal_connect_swapped(dialog, "response",
479 G_CALLBACK(gtk_widget_destroy),
480 dialog);
482 gtk_widget_show(dialog);
484 return;
487 debug("callback_do_join: Successfully joined %s\n",
488 new_workgroup_type);
490 dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_parent),
491 GTK_DIALOG_DESTROY_WITH_PARENT,
492 GTK_MESSAGE_INFO,
493 GTK_BUTTONS_OK,
494 "Welcome to the %s %s.",
495 state->name_buffer_new,
496 new_workgroup_type);
498 gtk_dialog_run(GTK_DIALOG(dialog));
499 gtk_widget_destroy(dialog);
501 callback_do_reboot(NULL, state->window_parent, state);
504 static void callback_creds_prompt(GtkWidget *widget,
505 gpointer data)
507 GtkWidget *window;
508 GtkWidget *box1;
509 GtkWidget *bbox;
510 GtkWidget *button;
511 GtkWidget *label;
513 struct join_state *state = (struct join_state *)data;
515 debug("callback_creds_prompt:\n");
517 state->window_parent = state->window_do_change;
519 if (state->hostname_changed) {
520 return callback_do_hostname_change(NULL, state);
523 if ((state->name_type_initial != NetSetupDomainName) &&
524 (state->name_type_new != NetSetupDomainName)) {
525 return callback_do_join(NULL, state);
528 window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
530 gtk_window_set_title(GTK_WINDOW(window), "Computer Name Changes");
531 gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
532 gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
533 gtk_widget_set_size_request(GTK_WIDGET(window), 380, 280);
534 gtk_window_set_icon_from_file(GTK_WINDOW(window), SAMBA_ICON_PATH, NULL);
535 /* gtk_window_set_icon_name(GTK_WIDGET(window), GTK_STOCK_DIALOG_AUTHENTICATION); */
536 state->window_creds_prompt = window;
538 g_signal_connect(G_OBJECT(window), "delete_event",
539 G_CALLBACK(callback_do_close), window);
541 gtk_container_set_border_width(GTK_CONTAINER(window), 10);
543 box1 = gtk_vbox_new(FALSE, 0);
545 gtk_container_add(GTK_CONTAINER(window), box1);
547 if ((state->name_type_initial == NetSetupDomainName) &&
548 (state->name_type_new == NetSetupWorkgroupName)) {
549 label = gtk_label_new("Enter the name and password of an account with permission to leave the domain.\n");
550 } else {
551 label = gtk_label_new("Enter the name and password of an account with permission to join the domain.\n");
553 gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
554 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
556 gtk_box_pack_start(GTK_BOX(box1), label, FALSE, FALSE, 0);
558 gtk_widget_show(label);
560 /* USER NAME */
561 label = gtk_label_new("User name:");
562 gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
563 gtk_box_pack_start(GTK_BOX(box1), label, FALSE, FALSE, 0);
564 gtk_widget_show(label);
566 state->entry_account = gtk_entry_new();
567 gtk_entry_set_max_length(GTK_ENTRY(state->entry_account), MAX_CRED_LEN);
568 g_signal_connect(G_OBJECT(state->entry_account), "activate",
569 G_CALLBACK(callback_return_username_and_enter),
570 (gpointer)state);
571 gtk_editable_select_region(GTK_EDITABLE(state->entry_account),
572 0, GTK_ENTRY(state->entry_account)->text_length);
573 gtk_box_pack_start(GTK_BOX(box1), state->entry_account, TRUE, TRUE, 0);
574 gtk_widget_show(state->entry_account);
576 /* PASSWORD */
577 label = gtk_label_new("Password:");
578 gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
579 gtk_box_pack_start(GTK_BOX(box1), label, FALSE, FALSE, 0);
580 gtk_widget_show(label);
582 state->entry_password = gtk_entry_new();
583 gtk_entry_set_max_length(GTK_ENTRY(state->entry_password), MAX_CRED_LEN);
584 gtk_entry_set_visibility(GTK_ENTRY(state->entry_password), FALSE);
585 g_signal_connect(G_OBJECT(state->entry_password), "activate",
586 G_CALLBACK(callback_return_password_and_enter),
587 (gpointer)state);
588 gtk_editable_set_editable(GTK_EDITABLE(state->entry_password), TRUE);
589 gtk_editable_select_region(GTK_EDITABLE(state->entry_password),
590 0, GTK_ENTRY(state->entry_password)->text_length);
591 gtk_box_pack_start(GTK_BOX(box1), state->entry_password, TRUE, TRUE, 0);
592 gtk_widget_show(state->entry_password);
594 bbox = gtk_hbutton_box_new();
595 gtk_container_set_border_width(GTK_CONTAINER(bbox), 5);
596 gtk_container_add(GTK_CONTAINER(box1), bbox);
597 gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
598 gtk_box_set_spacing(GTK_BOX(bbox), 10);
600 state->button_ok_creds = gtk_button_new_from_stock(GTK_STOCK_OK);
601 gtk_widget_grab_focus(GTK_WIDGET(state->button_ok_creds));
602 gtk_container_add(GTK_CONTAINER(bbox), state->button_ok_creds);
603 g_signal_connect(G_OBJECT(state->button_ok_creds), "clicked",
604 G_CALLBACK(callback_do_join),
605 (gpointer)state);
606 gtk_widget_show(state->button_ok_creds);
608 button = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
609 gtk_container_add(GTK_CONTAINER(bbox), button);
610 g_signal_connect(G_OBJECT(button), "clicked",
611 G_CALLBACK(callback_do_close), (gpointer) window);
612 gtk_widget_show_all(window);
615 static void callback_enter_hostname_and_unlock(GtkWidget *widget,
616 gpointer data)
618 const gchar *entry_text = NULL;
619 char *str = NULL;
620 struct join_state *state = (struct join_state *)data;
622 entry_text = gtk_entry_get_text(GTK_ENTRY(widget));
623 debug("callback_enter_hostname_and_unlock: %s\n", entry_text);
624 if (!entry_text || entry_text[0] == 0) {
625 state->hostname_changed = FALSE;
626 gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), FALSE);
627 return;
629 if (strcasecmp(state->my_hostname, entry_text) == 0) {
630 state->hostname_changed = FALSE;
631 gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), FALSE);
632 return;
634 state->hostname_changed = TRUE;
635 if (state->name_type_initial == NetSetupDomainName) {
636 asprintf(&str, "%s.%s", entry_text, state->my_dnsdomain);
637 } else {
638 asprintf(&str, "%s.", entry_text);
640 gtk_label_set_text(GTK_LABEL(state->label_full_computer_name), str);
641 free(str);
643 if (state->hostname_changed && str && str[0] != 0 && str[0] != '.') {
644 gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), TRUE);
648 static void callback_enter_computer_description_and_unlock(GtkWidget *widget,
649 gpointer data)
651 const gchar *entry_text = NULL;
652 struct join_state *state = (struct join_state *)data;
653 int string_unchanged = 0;
655 entry_text = gtk_entry_get_text(GTK_ENTRY(widget));
656 debug("callback_enter_computer_description_and_unlock: %s\n",
657 entry_text);
658 #if 0
659 if (!entry_text || entry_text[0] == 0) {
660 string_unchanged = 1;
661 gtk_widget_set_sensitive(GTK_WIDGET(state->button_apply),
662 FALSE);
663 return;
665 #endif
666 if (entry_text && strcasecmp(state->comment, entry_text) == 0) {
667 string_unchanged = 1;
668 gtk_widget_set_sensitive(GTK_WIDGET(state->button_apply),
669 FALSE);
670 return;
673 gtk_widget_set_sensitive(GTK_WIDGET(state->button_apply), TRUE);
674 SAFE_FREE(state->comment_new);
675 state->comment_new = strdup(entry_text);
680 static void callback_enter_workgroup_and_unlock(GtkWidget *widget,
681 gpointer data)
683 const gchar *entry_text = NULL;
684 struct join_state *state = (struct join_state *)data;
686 entry_text = gtk_entry_get_text(GTK_ENTRY(widget));
687 debug("callback_enter_workgroup_and_unlock: %s\n", entry_text);
688 if (!entry_text || entry_text[0] == 0) {
689 gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), FALSE);
690 return;
692 if (strcasecmp(state->name_buffer_initial, entry_text) == 0) {
693 gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), FALSE);
694 return;
696 gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), TRUE);
697 SAFE_FREE(state->name_buffer_new);
698 state->name_buffer_new = strdup(entry_text);
699 state->name_type_new = NetSetupWorkgroupName;
702 static void callback_enter_domain_and_unlock(GtkWidget *widget,
703 gpointer data)
705 const gchar *entry_text = NULL;
706 struct join_state *state = (struct join_state *)data;
708 entry_text = gtk_entry_get_text(GTK_ENTRY(widget));
709 debug("callback_enter_domain_and_unlock: %s\n", entry_text);
710 if (!entry_text || entry_text[0] == 0) {
711 gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), FALSE);
712 return;
714 if (strcasecmp(state->name_buffer_initial, entry_text) == 0) {
715 gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), FALSE);
716 return;
718 gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), TRUE);
719 SAFE_FREE(state->name_buffer_new);
720 state->name_buffer_new = strdup(entry_text);
721 state->name_type_new = NetSetupDomainName;
724 static void callback_continue(GtkWidget *widget,
725 gpointer data)
727 struct join_state *state = (struct join_state *)data;
729 gtk_widget_grab_focus(GTK_WIDGET(state->button_ok));
730 g_signal_emit_by_name(state->button_ok, "clicked");
733 static void callback_apply_continue(GtkWidget *widget,
734 gpointer data)
736 struct join_state *state = (struct join_state *)data;
738 gtk_widget_grab_focus(GTK_WIDGET(state->button_apply));
739 g_signal_emit_by_name(state->button_apply, "clicked");
742 static void callback_do_join_workgroup(GtkWidget *widget,
743 gpointer data)
745 struct join_state *state = (struct join_state *)data;
746 debug("callback_do_join_workgroup choosen\n");
747 gtk_widget_set_sensitive(GTK_WIDGET(state->entry_workgroup), TRUE);
748 gtk_widget_grab_focus(GTK_WIDGET(state->entry_workgroup));
749 gtk_widget_set_sensitive(GTK_WIDGET(state->entry_domain), FALSE);
750 callback_enter_workgroup_and_unlock(state->entry_workgroup, state); /* TEST */
753 static void callback_do_join_domain(GtkWidget *widget,
754 gpointer data)
756 struct join_state *state = (struct join_state *)data;
757 debug("callback_do_join_domain choosen\n");
758 gtk_widget_set_sensitive(GTK_WIDGET(state->entry_domain), TRUE);
759 gtk_widget_grab_focus(GTK_WIDGET(state->entry_domain));
760 gtk_widget_set_sensitive(GTK_WIDGET(state->entry_workgroup), FALSE);
761 callback_enter_domain_and_unlock(state->entry_domain, state); /* TEST */
764 static void callback_do_change(GtkWidget *widget,
765 gpointer data)
767 GtkWidget *window;
768 GtkWidget *box1;
769 GtkWidget *bbox;
770 GtkWidget *button_workgroup;
771 GtkWidget *button_domain;
772 GtkWidget *button;
773 GtkWidget *label;
774 GtkWidget *frame_horz;
775 GtkWidget *vbox;
776 GtkWidget *entry;
777 GSList *group;
779 struct join_state *state = (struct join_state *)data;
781 debug("callback_do_change called\n");
783 #if 0
784 /* FIXME: add proper warnings for Samba as a DC */
785 if (state->server_role == 3) {
786 GtkWidget *dialog;
787 dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_main),
788 GTK_DIALOG_DESTROY_WITH_PARENT,
789 GTK_MESSAGE_ERROR,
790 GTK_BUTTONS_OK,
791 "Domain controller cannot be moved from one domain to another, they must first be demoted. Renaming this domain controller may cause it to become temporarily unavailable to users and computers. For information on renaming domain controllers, including alternate renaming methods, see Help and Support. To continue renaming this domain controller, click OK.");
792 g_signal_connect_swapped(dialog, "response",
793 G_CALLBACK(gtk_widget_destroy),
794 dialog);
796 gtk_widget_show(dialog);
797 return;
799 #endif
801 state->button_ok = gtk_button_new_from_stock(GTK_STOCK_OK);
802 window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
804 gtk_window_set_title(GTK_WINDOW(window), "Computer Name Changes");
805 gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
806 gtk_widget_set_size_request(GTK_WIDGET(window), 480, 500);
807 gtk_window_set_icon_from_file(GTK_WINDOW(window), SAMBA_ICON_PATH, NULL);
809 g_signal_connect(G_OBJECT(window), "delete_event",
810 G_CALLBACK(callback_do_close), window);
812 gtk_container_set_border_width(GTK_CONTAINER(window), 10);
814 box1 = gtk_vbox_new(FALSE, 0);
815 gtk_container_add(GTK_CONTAINER(window), box1);
817 label = gtk_label_new("You can change the name and membership of this computer. Changes may affect access to network ressources.");
818 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
819 gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
820 gtk_box_pack_start(GTK_BOX(box1), label, TRUE, TRUE, 0);
821 gtk_widget_show(label);
823 /* COMPUTER NAME */
824 label = gtk_label_new("Computer name:");
825 gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
826 gtk_box_pack_start(GTK_BOX(box1), label, TRUE, TRUE, 0);
827 gtk_widget_show(label);
829 state->label_full_computer_name = gtk_label_new(NULL);
831 entry = gtk_entry_new();
832 gtk_entry_set_max_length(GTK_ENTRY(entry), MAX_NETBIOS_NAME_LEN);
833 g_signal_connect(G_OBJECT(entry), "changed",
834 G_CALLBACK(callback_enter_hostname_and_unlock),
835 (gpointer)state);
836 gtk_entry_set_text(GTK_ENTRY(entry), state->my_hostname);
837 gtk_editable_select_region(GTK_EDITABLE(entry),
838 0, GTK_ENTRY(entry)->text_length);
840 gtk_editable_set_editable(GTK_EDITABLE(entry), TRUE); /* ! */
841 gtk_box_pack_start(GTK_BOX(box1), entry, TRUE, TRUE, 0);
842 gtk_widget_show(entry);
845 /* FULL COMPUTER NAME */
846 label = gtk_label_new("Full computer name:");
847 gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
848 gtk_box_pack_start(GTK_BOX(box1), label, TRUE, TRUE, 0);
849 gtk_widget_show(label);
852 const gchar *entry_text;
853 char *str = NULL;
854 entry_text = gtk_entry_get_text(GTK_ENTRY(entry));
855 if (state->name_type_initial == NetSetupDomainName) {
856 asprintf(&str, "%s.%s", entry_text,
857 state->my_dnsdomain);
858 } else {
859 asprintf(&str, "%s.", entry_text);
861 gtk_label_set_text(GTK_LABEL(state->label_full_computer_name),
862 str);
863 free(str);
864 gtk_misc_set_alignment(GTK_MISC(state->label_full_computer_name), 0, 0);
865 gtk_box_pack_start(GTK_BOX(box1),
866 state->label_full_computer_name, TRUE, TRUE, 0);
867 gtk_widget_show(state->label_full_computer_name);
870 /* BOX */
871 frame_horz = gtk_frame_new ("Member Of");
872 gtk_box_pack_start(GTK_BOX(box1), frame_horz, TRUE, TRUE, 10);
874 vbox = gtk_vbox_new(FALSE, 0);
875 gtk_container_set_border_width(GTK_CONTAINER(vbox), 10);
876 gtk_container_add(GTK_CONTAINER(frame_horz), vbox);
878 /* TWO ENTRIES */
879 state->entry_workgroup = gtk_entry_new();
880 state->entry_domain = gtk_entry_new();
882 /* DOMAIN */
883 button_domain = gtk_radio_button_new_with_label(NULL, "Domain");
884 if (state->name_type_initial == NetSetupDomainName) {
885 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button_domain), TRUE);
887 gtk_box_pack_start(GTK_BOX(vbox), button_domain, TRUE, TRUE, 0);
888 g_signal_connect(G_OBJECT(button_domain), "clicked",
889 G_CALLBACK(callback_do_join_domain),
890 (gpointer)state);
893 gtk_entry_set_max_length(GTK_ENTRY(state->entry_domain), 50);
894 g_signal_connect(G_OBJECT(state->entry_domain), "changed",
895 G_CALLBACK(callback_enter_domain_and_unlock),
896 (gpointer)state);
897 g_signal_connect(G_OBJECT(state->entry_domain), "activate",
898 G_CALLBACK(callback_continue),
899 (gpointer)state);
900 if (state->name_type_initial == NetSetupDomainName) {
901 gtk_entry_set_text(GTK_ENTRY(state->entry_domain),
902 state->name_buffer_initial);
903 gtk_widget_set_sensitive(state->entry_workgroup, FALSE);
904 gtk_widget_set_sensitive(state->entry_domain, TRUE);
906 gtk_editable_set_editable(GTK_EDITABLE(state->entry_domain), TRUE);
907 gtk_box_pack_start(GTK_BOX(vbox), state->entry_domain, TRUE, TRUE, 0);
908 gtk_widget_show(state->entry_domain);
910 gtk_widget_show(button_domain);
912 /* WORKGROUP */
913 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button_domain));
914 button_workgroup = gtk_radio_button_new_with_label(group, "Workgroup");
915 if (state->name_type_initial == NetSetupWorkgroupName) {
916 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button_workgroup), TRUE);
918 gtk_box_pack_start(GTK_BOX(vbox), button_workgroup, TRUE, TRUE, 0);
919 g_signal_connect(G_OBJECT(button_workgroup), "clicked",
920 G_CALLBACK(callback_do_join_workgroup),
921 (gpointer)state);
923 gtk_entry_set_max_length(GTK_ENTRY(state->entry_workgroup),
924 MAX_NETBIOS_NAME_LEN);
925 g_signal_connect(G_OBJECT(state->entry_workgroup), "changed",
926 G_CALLBACK(callback_enter_workgroup_and_unlock),
927 (gpointer)state);
928 g_signal_connect(G_OBJECT(state->entry_workgroup), "activate",
929 G_CALLBACK(callback_continue),
930 (gpointer)state);
932 if (state->name_type_initial == NetSetupWorkgroupName) {
933 gtk_entry_set_text(GTK_ENTRY(state->entry_workgroup),
934 state->name_buffer_initial);
935 gtk_widget_set_sensitive(GTK_WIDGET(state->entry_domain), FALSE);
936 gtk_widget_set_sensitive(GTK_WIDGET(state->entry_workgroup), TRUE);
938 gtk_box_pack_start(GTK_BOX(vbox), state->entry_workgroup, TRUE, TRUE, 0);
939 gtk_widget_show(state->entry_workgroup);
941 gtk_widget_show(button_workgroup);
943 /* BUTTONS */
944 bbox = gtk_hbutton_box_new();
945 gtk_container_set_border_width(GTK_CONTAINER(bbox), 5);
946 gtk_container_add(GTK_CONTAINER(box1), bbox);
947 gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
948 gtk_box_set_spacing(GTK_BOX(bbox), 10);
950 state->window_do_change = window;
951 gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), FALSE); /* !!! */
952 gtk_container_add(GTK_CONTAINER(bbox), state->button_ok);
953 g_signal_connect(G_OBJECT(state->button_ok), "clicked",
954 G_CALLBACK(callback_creds_prompt),
955 (gpointer)state);
957 button = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
958 gtk_container_add(GTK_CONTAINER(bbox), button);
959 g_signal_connect(G_OBJECT(button), "clicked",
960 G_CALLBACK(callback_do_close),
961 (gpointer)window);
963 gtk_widget_show_all(window);
967 static void callback_do_about(GtkWidget *widget,
968 gpointer data)
970 GdkPixbuf *logo;
971 GError *error = NULL;
973 debug("callback_do_about called\n");
975 logo = gdk_pixbuf_new_from_file(SAMBA_IMAGE_PATH,
976 &error);
977 if (logo == NULL) {
978 g_print("failed to load logo from %s: %s\n",
979 SAMBA_IMAGE_PATH, error->message);
982 gtk_show_about_dialog(data,
983 "name", "Samba",
984 "version", "3.2.0pre2-GIT-904a90-test",
985 "copyright", "Copyright Andrew Tridgell and the Samba Team 1992-2007",
986 "website", "http://www.samba.org",
987 "license", "GPLv3",
988 "logo", logo,
989 "comments", "Samba gtk domain join utility",
990 NULL);
993 static int draw_main_window(struct join_state *state)
995 GtkWidget *window;
996 GtkWidget *button;
997 GtkWidget *label;
998 GtkWidget *main_vbox;
999 GtkWidget *vbox;
1000 GtkWidget *hbox;
1001 GtkWidget *bbox;
1002 GtkWidget *image;
1003 GtkWidget *table;
1004 GtkWidget *entry;
1005 GdkPixbuf *icon;
1006 GError *error = NULL;
1008 icon = gdk_pixbuf_new_from_file(SAMBA_ICON_PATH,
1009 &error);
1010 if (icon == NULL) {
1011 g_print("failed to load icon from %s : %s\n",
1012 SAMBA_ICON_PATH, error->message);
1015 #if 1
1016 image = gtk_image_new_from_file(SAMBA_IMAGE_PATH_SMALL);
1017 #else
1018 image = gtk_image_new_from_file("/usr/share/pixmaps/redhat-system_settings.png");
1019 #endif
1020 if (image == NULL) {
1021 g_print("failed to load logo from %s : %s\n",
1022 SAMBA_IMAGE_PATH_SMALL, error->message);
1025 window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
1026 state->window_main = window;
1028 gtk_window_set_title(GTK_WINDOW(window), "Samba - Join Domain dialogue");
1029 gtk_widget_set_size_request(GTK_WIDGET(window), 600, 600);
1030 gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
1031 gtk_window_set_icon_from_file(GTK_WINDOW(window), SAMBA_ICON_PATH, NULL);
1033 g_signal_connect(G_OBJECT(window), "delete_event",
1034 G_CALLBACK(callback_delete_event), NULL);
1036 gtk_container_set_border_width(GTK_CONTAINER(window), 10);
1038 main_vbox = gtk_vbox_new(FALSE, 10);
1039 gtk_container_add(GTK_CONTAINER(window), main_vbox);
1041 #if 0
1042 gtk_box_pack_start(GTK_BOX(main_vbox), image, TRUE, TRUE, 10);
1043 gtk_widget_show(image);
1044 #endif
1045 /* Hbox */
1046 hbox = gtk_hbox_new(FALSE, 10);
1047 gtk_container_add(GTK_CONTAINER(main_vbox), hbox);
1050 /* gtk_box_pack_start(GTK_BOX(main_vbox), image, TRUE, TRUE, 10); */
1051 /* gtk_misc_set_alignment(GTK_MISC(image), 0, 0); */
1052 gtk_widget_set_size_request(GTK_WIDGET(image), 150, 40);
1053 gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 10);
1054 gtk_widget_show(image);
1056 /* Label */
1057 label = gtk_label_new("Samba uses the following information to identify your computer on the network.");
1058 /* gtk_misc_set_alignment(GTK_MISC(label), 0, 0); */
1059 gtk_widget_set_size_request(GTK_WIDGET(label), 400, 40);
1060 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
1061 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
1062 gtk_widget_show(label);
1065 gtk_widget_show(hbox);
1067 vbox = gtk_vbox_new(FALSE, 0);
1068 gtk_container_set_border_width(GTK_CONTAINER(vbox), 10);
1069 gtk_container_add(GTK_CONTAINER(main_vbox), vbox);
1071 /* Table */
1072 table = gtk_table_new(6, 3, TRUE);
1073 gtk_table_set_row_spacings(GTK_TABLE(table), 5);
1074 gtk_table_set_col_spacings(GTK_TABLE(table), 5);
1075 gtk_container_add(GTK_CONTAINER(vbox), table);
1078 /* Label */
1079 label = gtk_label_new("Computer description:");
1080 /* gtk_misc_set_alignment(GTK_MISC(label), 0, 0); */
1081 gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 0, 1);
1082 gtk_widget_show(label);
1084 state->button_apply = gtk_button_new_from_stock(GTK_STOCK_APPLY);
1086 /* Entry */
1087 entry = gtk_entry_new();
1088 gtk_entry_set_max_length(GTK_ENTRY(entry), 256);
1089 g_signal_connect(G_OBJECT(entry), "changed",
1090 G_CALLBACK(callback_enter_computer_description_and_unlock),
1091 state);
1092 g_signal_connect(G_OBJECT(entry), "activate",
1093 G_CALLBACK(callback_apply_continue),
1094 (gpointer)state);
1096 gtk_entry_set_text(GTK_ENTRY(entry), (char *)state->comment);
1097 gtk_editable_set_editable(GTK_EDITABLE(entry), TRUE); /* ! */
1098 gtk_table_attach_defaults(GTK_TABLE(table), entry, 1, 3, 0, 1);
1099 gtk_widget_show(entry);
1102 /* Label */
1103 label = gtk_label_new("For example: \"Samba \%v\".");
1104 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
1105 gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
1106 gtk_table_attach_defaults(GTK_TABLE(table), label, 1, 3, 1, 2);
1107 gtk_widget_show(label);
1109 /* Label */
1110 label = gtk_label_new("Full computer name:");
1111 gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
1112 gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 2, 3);
1113 gtk_widget_show(label);
1116 /* Label */
1117 char *str = NULL;
1118 if (state->name_type_initial == NetSetupDomainName) {
1119 asprintf(&str, "%s.%s", state->my_hostname,
1120 state->my_dnsdomain);
1121 } else {
1122 asprintf(&str, "%s.", state->my_hostname);
1125 label = gtk_label_new(str);
1126 SAFE_FREE(str);
1127 gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
1128 gtk_table_attach_defaults(GTK_TABLE(table), label, 1, 3, 2, 3);
1129 gtk_widget_show(label);
1132 /* Label */
1133 if (state->name_type_initial == NetSetupDomainName) {
1134 label = gtk_label_new("Domain:");
1135 } else {
1136 label = gtk_label_new("Workgroup:");
1138 gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
1139 gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 3, 4);
1140 gtk_widget_show(label);
1141 state->label_current_name_type = label;
1143 /* Label */
1144 label = gtk_label_new(state->name_buffer_initial);
1145 gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
1146 gtk_table_attach_defaults(GTK_TABLE(table), label, 1, 3, 3, 4);
1147 gtk_widget_show(label);
1148 state->label_current_name_buffer = label;
1151 hbox = gtk_hbox_new(FALSE, 0);
1152 gtk_container_add(GTK_CONTAINER(vbox), hbox);
1153 label = gtk_label_new("To rename this computer or join a domain, click Change.");
1154 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
1159 /* bbox */
1160 bbox = gtk_hbutton_box_new();
1161 gtk_container_set_border_width(GTK_CONTAINER(bbox), 5);
1162 gtk_container_add(GTK_CONTAINER(hbox), bbox);
1163 gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
1164 gtk_box_set_spacing(GTK_BOX(bbox), 10);
1166 button = gtk_button_new_with_mnemonic("Ch_ange");
1167 g_signal_connect(G_OBJECT(button), "clicked",
1168 G_CALLBACK(callback_do_change),
1169 (gpointer)state);
1170 gtk_box_pack_start(GTK_BOX(bbox), button, TRUE, TRUE, 0);
1171 gtk_widget_show(button);
1173 /* Label (hidden) */
1174 state->label_reboot = gtk_label_new(NULL);
1175 gtk_label_set_line_wrap(GTK_LABEL(state->label_reboot), TRUE);
1176 gtk_misc_set_alignment(GTK_MISC(state->label_reboot), 0, 0);
1177 gtk_box_pack_start(GTK_BOX(vbox), state->label_reboot, TRUE, TRUE, 0);
1178 gtk_widget_show(state->label_reboot);
1180 #if 0
1181 gtk_box_pack_start(GTK_BOX(vbox),
1182 create_bbox(window, TRUE, NULL, 10, 85, 20, GTK_BUTTONBOX_END),
1183 TRUE, TRUE, 5);
1184 #endif
1187 GtkWidget *frame;
1188 GtkWidget *bbox2;
1189 GtkWidget *button2;
1191 frame = gtk_frame_new(NULL);
1192 bbox2 = gtk_hbutton_box_new();
1194 gtk_container_set_border_width(GTK_CONTAINER(bbox2), 5);
1195 gtk_container_add(GTK_CONTAINER(frame), bbox2);
1197 /* Set the appearance of the Button Box */
1198 gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox2), GTK_BUTTONBOX_END);
1199 gtk_box_set_spacing(GTK_BOX(bbox2), 10);
1200 /*gtk_button_box_set_child_size(GTK_BUTTON_BOX(bbox2), child_w, child_h);*/
1202 button2 = gtk_button_new_from_stock(GTK_STOCK_OK);
1203 gtk_container_add(GTK_CONTAINER(bbox2), button2);
1204 g_signal_connect(G_OBJECT(button2), "clicked", G_CALLBACK(callback_do_exit), state);
1206 button2 = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
1207 gtk_container_add(GTK_CONTAINER(bbox2), button2);
1208 g_signal_connect(G_OBJECT(button2), "clicked",
1209 G_CALLBACK(callback_delete_event),
1210 window);
1212 gtk_container_add(GTK_CONTAINER(bbox2), state->button_apply);
1213 g_signal_connect(G_OBJECT(state->button_apply), "clicked",
1214 G_CALLBACK(callback_apply_description_change),
1215 state);
1216 gtk_widget_set_sensitive(GTK_WIDGET(state->button_apply), FALSE);
1218 button2 = gtk_button_new_from_stock(GTK_STOCK_ABOUT);
1219 gtk_container_add(GTK_CONTAINER(bbox2), button2);
1220 g_signal_connect(G_OBJECT(button2), "clicked",
1221 G_CALLBACK(callback_do_about),
1222 window);
1224 gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 5);
1227 gtk_widget_show_all(window);
1229 return 0;
1232 static int init_join_state(struct join_state **state)
1234 struct join_state *s;
1236 s = malloc(sizeof(struct join_state));
1237 if (!s) {
1238 return -1;
1241 memset(s, '\0', sizeof(struct join_state));
1243 *state = s;
1245 return 0;
1248 static int initialize_join_state(struct join_state *state,
1249 const char *debug_level)
1251 struct libnetapi_ctx *ctx = NULL;
1252 NET_API_STATUS status = 0;
1254 status = libnetapi_init(&ctx);
1255 if (status) {
1256 return status;
1259 if (debug_level) {
1260 libnetapi_set_debuglevel(ctx, debug_level);
1264 char my_hostname[HOST_NAME_MAX];
1265 const char *p = NULL;
1266 if (gethostname(my_hostname, sizeof(my_hostname)) == -1) {
1267 return -1;
1270 state->my_fqdn = strdup(my_hostname);
1271 if (!state->my_fqdn) {
1272 return -1;
1275 p = strchr(my_hostname, '.');
1276 if (p) {
1277 my_hostname[strlen(my_hostname) - strlen(p)] = '\0';
1278 state->my_hostname = strdup(my_hostname);
1279 if (!state->my_hostname) {
1280 return -1;
1282 p++;
1283 state->my_dnsdomain = strdup(p);
1284 if (!state->my_dnsdomain) {
1285 return -1;
1291 const char *buffer = NULL;
1292 uint16_t type = 0;
1293 status = NetGetJoinInformation(NULL, &buffer, &type);
1294 if (status) {
1295 return status;
1297 state->name_buffer_initial = strdup(buffer);
1298 if (!state->name_buffer_initial) {
1299 return -1;
1301 state->name_type_initial = type;
1302 NetApiBufferFree((void *)buffer);
1306 struct srvsvc_NetSrvInfo1005 *info1005 = NULL;
1307 uint8_t *buffer = NULL;
1309 status = NetServerGetInfo(NULL, 1005, &buffer);
1310 if (status) {
1311 return status;
1314 info1005 = (struct srvsvc_NetSrvInfo1005 *)buffer;
1316 state->comment = strdup(info1005->comment);
1317 if (!state->comment) {
1318 return -1;
1320 NetApiBufferFree(buffer);
1322 #if 0
1324 struct srvsvc_NetSrvInfo100 *info100 = NULL;
1325 uint8_t *buffer = NULL;
1327 status = NetServerGetInfo(NULL, 100, &buffer);
1328 if (status) {
1329 return status;
1332 info100 = (struct srvsvc_NetSrvInfo100 *)buffer;
1334 state->comment = strdup(info100->comment);
1335 if (!state->comment) {
1336 return -1;
1339 #endif
1341 state->ctx = ctx;
1343 return 0;
1346 int main(int argc, char **argv)
1348 GOptionContext *context = NULL;
1349 static const char *debug_level = NULL;
1350 struct join_state *state = NULL;
1351 GError *error = NULL;
1352 int ret = 0;
1354 static GOptionEntry entries[] = {
1355 { "debug", 'd', 0, G_OPTION_ARG_STRING, &debug_level, "Debug level (for samba)", "N" },
1356 { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, "Verbose output", 0 },
1357 { NULL }
1360 context = g_option_context_new("- Samba domain join utility");
1361 g_option_context_add_main_entries(context, entries, NULL);
1362 /* g_option_context_add_main_entries(context, entries, GETTEXT_PACKAGE); */
1363 g_option_context_add_group(context, gtk_get_option_group(TRUE));
1364 g_option_context_parse(context, &argc, &argv, &error);
1366 gtk_init(&argc, &argv);
1367 g_set_application_name("Samba");
1369 ret = init_join_state(&state);
1370 if (ret) {
1371 return ret;
1374 ret = initialize_join_state(state, debug_level);
1375 if (ret) {
1376 return ret;
1379 draw_main_window(state);
1381 gtk_main();
1383 do_cleanup(state);
1385 return 0;