allow selection of the organisational unit when joining a realm
[ira/wip.git] / source3 / utils / net_ads.c
1 /* 
2    Samba Unix/Linux SMB client library 
3    Version 3.0
4    net ads commands
5    Copyright (C) 2001 Andrew Tridgell (tridge@samba.org)
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  
20 */
21
22 #include "includes.h"
23
24 #ifdef HAVE_ADS
25
26 int net_ads_usage(int argc, const char **argv)
27 {
28         d_printf(
29 "\nnet ads join <org_unit>"\
30 "\n\tjoins the local machine to a ADS realm\n"\
31 "\nnet ads leave"\
32 "\n\tremoves the local machine from a ADS realm\n"\
33 "\nnet ads user"\
34 "\n\tlist users in the realm\n"\
35 "\nnet ads group"\
36 "\n\tlist groups in the realm\n"\
37 "\nnet ads info"\
38 "\n\tshows some info on the server\n"\
39 "\nnet ads status"\
40 "\n\tdump the machine account details to stdout\n"
41                 );
42         return -1;
43 }
44
45
46 static int net_ads_info(int argc, const char **argv)
47 {
48         ADS_STRUCT *ads;
49
50         ads = ads_init(NULL, NULL, NULL, NULL);
51         ads_connect(ads);
52
53         if (!ads) {
54                 d_printf("Didn't find the ldap server!\n");
55                 return -1;
56         }
57
58         d_printf("LDAP server: %s\n", ads->ldap_server);
59         d_printf("LDAP server name: %s\n", ads->ldap_server_name);
60         d_printf("Realm: %s\n", ads->realm);
61         d_printf("Bind Path: %s\n", ads->bind_path);
62         d_printf("LDAP port: %d\n", ads->ldap_port);
63
64         return 0;
65 }
66
67
68 static ADS_STRUCT *ads_startup(void)
69 {
70         ADS_STRUCT *ads;
71         int rc;
72         extern char *opt_password;
73         extern char *opt_user_name;
74
75         ads = ads_init(NULL, NULL, NULL, NULL);
76
77         if (!opt_user_name) {
78                 opt_user_name = "administrator";
79         }
80
81         if (!opt_password) {
82                 char *prompt;
83                 asprintf(&prompt,"%s password: ", opt_user_name);
84                 opt_password = getpass(prompt);
85                 free(prompt);
86         }
87         ads->password = strdup(opt_password);
88         ads->user_name = strdup(opt_user_name);
89
90         rc = ads_connect(ads);
91         if (rc) {
92                 d_printf("ads_connect: %s\n", ads_errstr(rc));
93                 return NULL;
94         }
95         return ads;
96 }
97
98 static int net_ads_user(int argc, const char **argv)
99 {
100         ADS_STRUCT *ads;
101         int rc;
102         void *res;
103         const char *attrs[] = {"sAMAccountName", "name", "objectSid", NULL};
104
105         if (!(ads = ads_startup())) return -1;
106         rc = ads_search(ads, &res, "(objectclass=user)", attrs);
107         if (rc) {
108                 d_printf("ads_search: %s\n", ads_errstr(rc));
109                 return -1;
110         }
111
112         if (ads_count_replies(ads, res) == 0) {
113                 d_printf("No users found\n");
114                 return -1;
115         }
116
117         ads_dump(ads, res);
118         ads_destroy(&ads);
119         return 0;
120 }
121
122 static int net_ads_group(int argc, const char **argv)
123 {
124         ADS_STRUCT *ads;
125         int rc;
126         void *res;
127         const char *attrs[] = {"sAMAccountName", "name", "objectSid", NULL};
128
129         if (!(ads = ads_startup())) return -1;
130         rc = ads_search(ads, &res, "(objectclass=group)", attrs);
131         if (rc) {
132                 d_printf("ads_search: %s\n", ads_errstr(rc));
133                 return -1;
134         }
135
136         if (ads_count_replies(ads, res) == 0) {
137                 d_printf("No groups found\n");
138                 return -1;
139         }
140
141         ads_dump(ads, res);
142         return 0;
143 }
144
145 static int net_ads_status(int argc, const char **argv)
146 {
147         ADS_STRUCT *ads;
148         int rc;
149         extern pstring global_myname;
150         void *res;
151
152         if (!(ads = ads_startup())) return -1;
153
154         rc = ads_find_machine_acct(ads, &res, global_myname);
155         if (rc) {
156                 d_printf("ads_find_machine_acct: %s\n", ads_errstr(rc));
157                 return -1;
158         }
159
160         if (ads_count_replies(ads, res) == 0) {
161                 d_printf("No machine account for '%s' found\n", global_myname);
162                 return -1;
163         }
164
165         ads_dump(ads, res);
166
167         return 0;
168 }
169
170 static int net_ads_leave(int argc, const char **argv)
171 {
172         ADS_STRUCT *ads = NULL;
173         int rc;
174         extern pstring global_myname;
175
176         if (!(ads = ads_startup())) {
177                 return -1;
178         }
179
180         if (!secrets_init()) {
181                 DEBUG(1,("Failed to initialise secrets database\n"));
182                 return -1;
183         }
184
185         rc = ads_leave_realm(ads, global_myname);
186         if (rc) {
187             d_printf("Failed to delete host '%s' from the '%s' realm.\n", 
188                      global_myname, ads->realm);
189             return -1;
190         }
191
192         d_printf("Removed '%s' from realm '%s'\n", global_myname, ads->realm);
193
194         return 0;
195 }
196
197 static int net_ads_join(int argc, const char **argv)
198 {
199         ADS_STRUCT *ads;
200         int rc;
201         char *password;
202         char *tmp_password;
203         extern pstring global_myname;
204         NTSTATUS status;
205         const char *org_unit = "Computers";
206         char *dn;
207         void *res;
208
209         if (argc > 0) org_unit = argv[0];
210
211         if (!secrets_init()) {
212                 DEBUG(1,("Failed to initialise secrets database\n"));
213                 return -1;
214         }
215
216         tmp_password = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH);
217         password = strdup(tmp_password);
218
219         if (!(ads = ads_startup())) return -1;
220
221         asprintf(&dn, "cn=%s,%s", org_unit, ads->bind_path);
222
223         rc = ads_search_dn(ads, &res, dn, NULL);
224         free(dn);
225         ads_msgfree(ads, res);
226
227         if (rc == LDAP_NO_SUCH_OBJECT) {
228                 d_printf("ads_join_realm: organisational unit %s does not exist\n", org_unit);
229                 return rc;
230         }
231
232         if (rc) {
233                 d_printf("ads_join_realm: %s\n", ads_errstr(rc));
234                 return -1;
235         }       
236
237         rc = ads_join_realm(ads, global_myname, org_unit);
238         if (rc) {
239                 d_printf("ads_join_realm: %s\n", ads_errstr(rc));
240                 return -1;
241         }
242
243         status = ads_set_machine_password(ads, global_myname, password);
244         if (!NT_STATUS_IS_OK(status)) {
245                 d_printf("ads_set_machine_password: %s\n", get_nt_error_msg(status));
246                 return -1;
247         }
248
249         if (!secrets_store_machine_password(password)) {
250                 DEBUG(1,("Failed to save machine password\n"));
251                 return -1;
252         }
253
254         d_printf("Joined '%s' to realm '%s'\n", global_myname, ads->realm);
255
256         free(password);
257
258         return 0;
259 }
260
261 int net_ads(int argc, const char **argv)
262 {
263         struct functable func[] = {
264                 {"INFO", net_ads_info},
265                 {"JOIN", net_ads_join},
266                 {"LEAVE", net_ads_leave},
267                 {"STATUS", net_ads_status},
268                 {"USER", net_ads_user},
269                 {"GROUP", net_ads_group},
270                 {NULL, NULL}
271         };
272         
273         return net_run_function(argc, argv, func, net_ads_usage);
274 }
275
276 #else
277
278 int net_ads_usage(int argc, const char **argv)
279 {
280         d_printf("ADS support not compiled in\n");
281         return -1;
282 }
283
284 int net_ads(int argc, const char **argv)
285 {
286         return net_ads_usage(argc, argv);
287 }
288
289 #endif