~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source3/utils/net_util.c

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  Unix SMB/CIFS implementation.
 
3
 *  Helper routines for net
 
4
 *  Copyright (C) Volker Lendecke 2006
 
5
 *  Copyright (C) Kai Blin 2008
 
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 3 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, see <http://www.gnu.org/licenses/>.
 
19
 */
 
20
 
 
21
 
 
22
#include "includes.h"
 
23
#include "utils/net.h"
 
24
 
 
25
NTSTATUS net_rpc_lookup_name(struct net_context *c,
 
26
                             TALLOC_CTX *mem_ctx, struct cli_state *cli,
 
27
                             const char *name, const char **ret_domain,
 
28
                             const char **ret_name, DOM_SID *ret_sid,
 
29
                             enum lsa_SidType *ret_type)
 
30
{
 
31
        struct rpc_pipe_client *lsa_pipe;
 
32
        struct policy_handle pol;
 
33
        NTSTATUS result = NT_STATUS_OK;
 
34
        const char **dom_names;
 
35
        DOM_SID *sids;
 
36
        enum lsa_SidType *types;
 
37
 
 
38
        ZERO_STRUCT(pol);
 
39
 
 
40
        result = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc.syntax_id,
 
41
                                          &lsa_pipe);
 
42
        if (!NT_STATUS_IS_OK(result)) {
 
43
                d_fprintf(stderr, "Could not initialise lsa pipe\n");
 
44
                return result;
 
45
        }
 
46
 
 
47
        result = rpccli_lsa_open_policy(lsa_pipe, mem_ctx, false,
 
48
                                        SEC_FLAG_MAXIMUM_ALLOWED,
 
49
                                        &pol);
 
50
        if (!NT_STATUS_IS_OK(result)) {
 
51
                d_fprintf(stderr, "open_policy failed: %s\n",
 
52
                          nt_errstr(result));
 
53
                return result;
 
54
        }
 
55
 
 
56
        result = rpccli_lsa_lookup_names(lsa_pipe, mem_ctx, &pol, 1,
 
57
                                         &name, &dom_names, 1, &sids, &types);
 
58
 
 
59
        if (!NT_STATUS_IS_OK(result)) {
 
60
                /* This can happen easily, don't log an error */
 
61
                goto done;
 
62
        }
 
63
 
 
64
        if (ret_domain != NULL) {
 
65
                *ret_domain = dom_names[0];
 
66
        }
 
67
        if (ret_name != NULL) {
 
68
                *ret_name = talloc_strdup(mem_ctx, name);
 
69
        }
 
70
        if (ret_sid != NULL) {
 
71
                sid_copy(ret_sid, &sids[0]);
 
72
        }
 
73
        if (ret_type != NULL) {
 
74
                *ret_type = types[0];
 
75
        }
 
76
 
 
77
 done:
 
78
        if (is_valid_policy_hnd(&pol)) {
 
79
                rpccli_lsa_Close(lsa_pipe, mem_ctx, &pol);
 
80
        }
 
81
        TALLOC_FREE(lsa_pipe);
 
82
 
 
83
        return result;
 
84
}
 
85
 
 
86
/****************************************************************************
 
87
 Connect to \\server\service.
 
88
****************************************************************************/
 
89
 
 
90
NTSTATUS connect_to_service(struct net_context *c,
 
91
                                        struct cli_state **cli_ctx,
 
92
                                        struct sockaddr_storage *server_ss,
 
93
                                        const char *server_name,
 
94
                                        const char *service_name,
 
95
                                        const char *service_type)
 
96
{
 
97
        NTSTATUS nt_status;
 
98
        int flags = 0;
 
99
 
 
100
        c->opt_password = net_prompt_pass(c, c->opt_user_name);
 
101
 
 
102
        if (c->opt_kerberos) {
 
103
                flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
 
104
        }
 
105
 
 
106
        if (c->opt_kerberos && c->opt_password) {
 
107
                flags |= CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS;
 
108
        }
 
109
 
 
110
        nt_status = cli_full_connection(cli_ctx, NULL, server_name,
 
111
                                        server_ss, c->opt_port,
 
112
                                        service_name, service_type,
 
113
                                        c->opt_user_name, c->opt_workgroup,
 
114
                                        c->opt_password, flags, Undefined, NULL);
 
115
        if (!NT_STATUS_IS_OK(nt_status)) {
 
116
                d_fprintf(stderr, "Could not connect to server %s\n", server_name);
 
117
 
 
118
                /* Display a nicer message depending on the result */
 
119
 
 
120
                if (NT_STATUS_V(nt_status) ==
 
121
                    NT_STATUS_V(NT_STATUS_LOGON_FAILURE))
 
122
                        d_fprintf(stderr, "The username or password was not correct.\n");
 
123
 
 
124
                if (NT_STATUS_V(nt_status) ==
 
125
                    NT_STATUS_V(NT_STATUS_ACCOUNT_LOCKED_OUT))
 
126
                        d_fprintf(stderr, "The account was locked out.\n");
 
127
 
 
128
                if (NT_STATUS_V(nt_status) ==
 
129
                    NT_STATUS_V(NT_STATUS_ACCOUNT_DISABLED))
 
130
                        d_fprintf(stderr, "The account was disabled.\n");
 
131
                return nt_status;
 
132
        }
 
133
 
 
134
        if (c->smb_encrypt) {
 
135
                nt_status = cli_force_encryption(*cli_ctx,
 
136
                                        c->opt_user_name,
 
137
                                        c->opt_password,
 
138
                                        c->opt_workgroup);
 
139
 
 
140
                if (NT_STATUS_EQUAL(nt_status,NT_STATUS_NOT_SUPPORTED)) {
 
141
                        d_printf("Encryption required and "
 
142
                                "server that doesn't support "
 
143
                                "UNIX extensions - failing connect\n");
 
144
                } else if (NT_STATUS_EQUAL(nt_status,NT_STATUS_UNKNOWN_REVISION)) {
 
145
                        d_printf("Encryption required and "
 
146
                                "can't get UNIX CIFS extensions "
 
147
                                "version from server.\n");
 
148
                } else if (NT_STATUS_EQUAL(nt_status,NT_STATUS_UNSUPPORTED_COMPRESSION)) {
 
149
                        d_printf("Encryption required and "
 
150
                                "share %s doesn't support "
 
151
                                "encryption.\n", service_name);
 
152
                } else if (!NT_STATUS_IS_OK(nt_status)) {
 
153
                        d_printf("Encryption required and "
 
154
                                "setup failed with error %s.\n",
 
155
                                nt_errstr(nt_status));
 
156
                }
 
157
 
 
158
                if (!NT_STATUS_IS_OK(nt_status)) {
 
159
                        cli_shutdown(*cli_ctx);
 
160
                        *cli_ctx = NULL;
 
161
                }
 
162
        }
 
163
 
 
164
        return nt_status;
 
165
}
 
166
 
 
167
/****************************************************************************
 
168
 Connect to \\server\ipc$.
 
169
****************************************************************************/
 
170
 
 
171
NTSTATUS connect_to_ipc(struct net_context *c,
 
172
                        struct cli_state **cli_ctx,
 
173
                        struct sockaddr_storage *server_ss,
 
174
                        const char *server_name)
 
175
{
 
176
        return connect_to_service(c, cli_ctx, server_ss, server_name, "IPC$",
 
177
                                  "IPC");
 
178
}
 
179
 
 
180
/****************************************************************************
 
181
 Connect to \\server\ipc$ anonymously.
 
182
****************************************************************************/
 
183
 
 
184
NTSTATUS connect_to_ipc_anonymous(struct net_context *c,
 
185
                                struct cli_state **cli_ctx,
 
186
                                struct sockaddr_storage *server_ss,
 
187
                                const char *server_name)
 
188
{
 
189
        NTSTATUS nt_status;
 
190
 
 
191
        nt_status = cli_full_connection(cli_ctx, c->opt_requester_name,
 
192
                                        server_name, server_ss, c->opt_port,
 
193
                                        "IPC$", "IPC",
 
194
                                        "", "",
 
195
                                        "", 0, Undefined, NULL);
 
196
 
 
197
        if (NT_STATUS_IS_OK(nt_status)) {
 
198
                return nt_status;
 
199
        } else {
 
200
                DEBUG(1,("Cannot connect to server (anonymously).  Error was %s\n", nt_errstr(nt_status)));
 
201
                return nt_status;
 
202
        }
 
203
}
 
204
 
 
205
/****************************************************************************
 
206
 Return malloced user@realm for krb5 login.
 
207
****************************************************************************/
 
208
 
 
209
static char *get_user_and_realm(const char *username)
 
210
{
 
211
        char *user_and_realm = NULL;
 
212
 
 
213
        if (!username) {
 
214
                return NULL;
 
215
        }
 
216
        if (strchr_m(username, '@')) {
 
217
                user_and_realm = SMB_STRDUP(username);
 
218
        } else {
 
219
                if (asprintf(&user_and_realm, "%s@%s", username, lp_realm()) == -1) {
 
220
                        user_and_realm = NULL;
 
221
                }
 
222
        }
 
223
        return user_and_realm;
 
224
}
 
225
 
 
226
/****************************************************************************
 
227
 Connect to \\server\ipc$ using KRB5.
 
228
****************************************************************************/
 
229
 
 
230
NTSTATUS connect_to_ipc_krb5(struct net_context *c,
 
231
                        struct cli_state **cli_ctx,
 
232
                        struct sockaddr_storage *server_ss,
 
233
                        const char *server_name)
 
234
{
 
235
        NTSTATUS nt_status;
 
236
        char *user_and_realm = NULL;
 
237
 
 
238
        /* FIXME: Should get existing kerberos ticket if possible. */
 
239
        c->opt_password = net_prompt_pass(c, c->opt_user_name);
 
240
        if (!c->opt_password) {
 
241
                return NT_STATUS_NO_MEMORY;
 
242
        }
 
243
 
 
244
        user_and_realm = get_user_and_realm(c->opt_user_name);
 
245
        if (!user_and_realm) {
 
246
                return NT_STATUS_NO_MEMORY;
 
247
        }
 
248
 
 
249
        nt_status = cli_full_connection(cli_ctx, NULL, server_name,
 
250
                                        server_ss, c->opt_port,
 
251
                                        "IPC$", "IPC",
 
252
                                        user_and_realm, c->opt_workgroup,
 
253
                                        c->opt_password,
 
254
                                        CLI_FULL_CONNECTION_USE_KERBEROS,
 
255
                                        Undefined, NULL);
 
256
 
 
257
        SAFE_FREE(user_and_realm);
 
258
 
 
259
        if (!NT_STATUS_IS_OK(nt_status)) {
 
260
                DEBUG(1,("Cannot connect to server using kerberos.  Error was %s\n", nt_errstr(nt_status)));
 
261
                return nt_status;
 
262
        }
 
263
 
 
264
        if (c->smb_encrypt) {
 
265
                nt_status = cli_cm_force_encryption(*cli_ctx,
 
266
                                        user_and_realm,
 
267
                                        c->opt_password,
 
268
                                        c->opt_workgroup,
 
269
                                        "IPC$");
 
270
                if (!NT_STATUS_IS_OK(nt_status)) {
 
271
                        cli_shutdown(*cli_ctx);
 
272
                        *cli_ctx = NULL;
 
273
                }
 
274
        }
 
275
 
 
276
        return nt_status;
 
277
}
 
278
 
 
279
/**
 
280
 * Connect a server and open a given pipe
 
281
 *
 
282
 * @param cli_dst               A cli_state
 
283
 * @param pipe                  The pipe to open
 
284
 * @param got_pipe              boolean that stores if we got a pipe
 
285
 *
 
286
 * @return Normal NTSTATUS return.
 
287
 **/
 
288
NTSTATUS connect_dst_pipe(struct net_context *c, struct cli_state **cli_dst,
 
289
                          struct rpc_pipe_client **pp_pipe_hnd,
 
290
                          const struct ndr_syntax_id *interface)
 
291
{
 
292
        NTSTATUS nt_status;
 
293
        char *server_name = SMB_STRDUP("127.0.0.1");
 
294
        struct cli_state *cli_tmp = NULL;
 
295
        struct rpc_pipe_client *pipe_hnd = NULL;
 
296
 
 
297
        if (server_name == NULL) {
 
298
                return NT_STATUS_NO_MEMORY;
 
299
        }
 
300
 
 
301
        if (c->opt_destination) {
 
302
                SAFE_FREE(server_name);
 
303
                if ((server_name = SMB_STRDUP(c->opt_destination)) == NULL) {
 
304
                        return NT_STATUS_NO_MEMORY;
 
305
                }
 
306
        }
 
307
 
 
308
        /* make a connection to a named pipe */
 
309
        nt_status = connect_to_ipc(c, &cli_tmp, NULL, server_name);
 
310
        if (!NT_STATUS_IS_OK(nt_status)) {
 
311
                SAFE_FREE(server_name);
 
312
                return nt_status;
 
313
        }
 
314
 
 
315
        nt_status = cli_rpc_pipe_open_noauth(cli_tmp, interface,
 
316
                                             &pipe_hnd);
 
317
        if (!NT_STATUS_IS_OK(nt_status)) {
 
318
                DEBUG(0, ("couldn't not initialize pipe\n"));
 
319
                cli_shutdown(cli_tmp);
 
320
                SAFE_FREE(server_name);
 
321
                return nt_status;
 
322
        }
 
323
 
 
324
        *cli_dst = cli_tmp;
 
325
        *pp_pipe_hnd = pipe_hnd;
 
326
        SAFE_FREE(server_name);
 
327
 
 
328
        return nt_status;
 
329
}
 
330
 
 
331
/****************************************************************************
 
332
 Use the local machine account (krb) and password for this session.
 
333
****************************************************************************/
 
334
 
 
335
int net_use_krb_machine_account(struct net_context *c)
 
336
{
 
337
        char *user_name = NULL;
 
338
 
 
339
        if (!secrets_init()) {
 
340
                d_fprintf(stderr, "ERROR: Unable to open secrets database\n");
 
341
                exit(1);
 
342
        }
 
343
 
 
344
        c->opt_password = secrets_fetch_machine_password(
 
345
                                c->opt_target_workgroup, NULL, NULL);
 
346
        if (asprintf(&user_name, "%s$@%s", global_myname(), lp_realm()) == -1) {
 
347
                return -1;
 
348
        }
 
349
        c->opt_user_name = user_name;
 
350
        return 0;
 
351
}
 
352
 
 
353
/****************************************************************************
 
354
 Use the machine account name and password for this session.
 
355
****************************************************************************/
 
356
 
 
357
int net_use_machine_account(struct net_context *c)
 
358
{
 
359
        char *user_name = NULL;
 
360
 
 
361
        if (!secrets_init()) {
 
362
                d_fprintf(stderr, "ERROR: Unable to open secrets database\n");
 
363
                exit(1);
 
364
        }
 
365
 
 
366
        c->opt_password = secrets_fetch_machine_password(
 
367
                                c->opt_target_workgroup, NULL, NULL);
 
368
        if (asprintf(&user_name, "%s$", global_myname()) == -1) {
 
369
                return -1;
 
370
        }
 
371
        c->opt_user_name = user_name;
 
372
        return 0;
 
373
}
 
374
 
 
375
bool net_find_server(struct net_context *c,
 
376
                        const char *domain,
 
377
                        unsigned flags,
 
378
                        struct sockaddr_storage *server_ss,
 
379
                        char **server_name)
 
380
{
 
381
        const char *d = domain ? domain : c->opt_target_workgroup;
 
382
 
 
383
        if (c->opt_host) {
 
384
                *server_name = SMB_STRDUP(c->opt_host);
 
385
        }
 
386
 
 
387
        if (c->opt_have_ip) {
 
388
                *server_ss = c->opt_dest_ip;
 
389
                if (!*server_name) {
 
390
                        char addr[INET6_ADDRSTRLEN];
 
391
                        print_sockaddr(addr, sizeof(addr), &c->opt_dest_ip);
 
392
                        *server_name = SMB_STRDUP(addr);
 
393
                }
 
394
        } else if (*server_name) {
 
395
                /* resolve the IP address */
 
396
                if (!resolve_name(*server_name, server_ss, 0x20))  {
 
397
                        DEBUG(1,("Unable to resolve server name\n"));
 
398
                        return false;
 
399
                }
 
400
        } else if (flags & NET_FLAGS_PDC) {
 
401
                fstring dc_name;
 
402
                struct sockaddr_storage pdc_ss;
 
403
 
 
404
                if (!get_pdc_ip(d, &pdc_ss)) {
 
405
                        DEBUG(1,("Unable to resolve PDC server address\n"));
 
406
                        return false;
 
407
                }
 
408
 
 
409
                if (is_zero_addr((struct sockaddr *)&pdc_ss)) {
 
410
                        return false;
 
411
                }
 
412
 
 
413
                if (!name_status_find(d, 0x1b, 0x20, &pdc_ss, dc_name)) {
 
414
                        return false;
 
415
                }
 
416
 
 
417
                *server_name = SMB_STRDUP(dc_name);
 
418
                *server_ss = pdc_ss;
 
419
        } else if (flags & NET_FLAGS_DMB) {
 
420
                struct sockaddr_storage msbrow_ss;
 
421
                char addr[INET6_ADDRSTRLEN];
 
422
 
 
423
                /*  if (!resolve_name(MSBROWSE, &msbrow_ip, 1)) */
 
424
                if (!resolve_name(d, &msbrow_ss, 0x1B))  {
 
425
                        DEBUG(1,("Unable to resolve domain browser via name lookup\n"));
 
426
                        return false;
 
427
                }
 
428
                *server_ss = msbrow_ss;
 
429
                print_sockaddr(addr, sizeof(addr), server_ss);
 
430
                *server_name = SMB_STRDUP(addr);
 
431
        } else if (flags & NET_FLAGS_MASTER) {
 
432
                struct sockaddr_storage brow_ss;
 
433
                char addr[INET6_ADDRSTRLEN];
 
434
                if (!resolve_name(d, &brow_ss, 0x1D))  {
 
435
                                /* go looking for workgroups */
 
436
                        DEBUG(1,("Unable to resolve master browser via name lookup\n"));
 
437
                        return false;
 
438
                }
 
439
                *server_ss = brow_ss;
 
440
                print_sockaddr(addr, sizeof(addr), server_ss);
 
441
                *server_name = SMB_STRDUP(addr);
 
442
        } else if (!(flags & NET_FLAGS_LOCALHOST_DEFAULT_INSANE)) {
 
443
                if (!interpret_string_addr(server_ss,
 
444
                                        "127.0.0.1", AI_NUMERICHOST)) {
 
445
                        DEBUG(1,("Unable to resolve 127.0.0.1\n"));
 
446
                        return false;
 
447
                }
 
448
                *server_name = SMB_STRDUP("127.0.0.1");
 
449
        }
 
450
 
 
451
        if (!*server_name) {
 
452
                DEBUG(1,("no server to connect to\n"));
 
453
                return false;
 
454
        }
 
455
 
 
456
        return true;
 
457
}
 
458
 
 
459
bool net_find_pdc(struct sockaddr_storage *server_ss,
 
460
                fstring server_name,
 
461
                const char *domain_name)
 
462
{
 
463
        if (!get_pdc_ip(domain_name, server_ss)) {
 
464
                return false;
 
465
        }
 
466
        if (is_zero_addr((struct sockaddr *)server_ss)) {
 
467
                return false;
 
468
        }
 
469
 
 
470
        if (!name_status_find(domain_name, 0x1b, 0x20, server_ss, server_name)) {
 
471
                return false;
 
472
        }
 
473
 
 
474
        return true;
 
475
}
 
476
 
 
477
NTSTATUS net_make_ipc_connection(struct net_context *c, unsigned flags,
 
478
                                 struct cli_state **pcli)
 
479
{
 
480
        return net_make_ipc_connection_ex(c, c->opt_workgroup, NULL, NULL, flags, pcli);
 
481
}
 
482
 
 
483
NTSTATUS net_make_ipc_connection_ex(struct net_context *c ,const char *domain,
 
484
                                    const char *server,
 
485
                                    struct sockaddr_storage *pss,
 
486
                                    unsigned flags, struct cli_state **pcli)
 
487
{
 
488
        char *server_name = NULL;
 
489
        struct sockaddr_storage server_ss;
 
490
        struct cli_state *cli = NULL;
 
491
        NTSTATUS nt_status;
 
492
 
 
493
        if ( !server || !pss ) {
 
494
                if (!net_find_server(c, domain, flags, &server_ss,
 
495
                                     &server_name)) {
 
496
                        d_fprintf(stderr, "Unable to find a suitable server "
 
497
                                "for domain %s\n", domain);
 
498
                        nt_status = NT_STATUS_UNSUCCESSFUL;
 
499
                        goto done;
 
500
                }
 
501
        } else {
 
502
                server_name = SMB_STRDUP( server );
 
503
                server_ss = *pss;
 
504
        }
 
505
 
 
506
        if (flags & NET_FLAGS_ANONYMOUS) {
 
507
                nt_status = connect_to_ipc_anonymous(c, &cli, &server_ss,
 
508
                                                     server_name);
 
509
        } else {
 
510
                nt_status = connect_to_ipc(c, &cli, &server_ss,
 
511
                                           server_name);
 
512
        }
 
513
 
 
514
        /* store the server in the affinity cache if it was a PDC */
 
515
 
 
516
        if ( (flags & NET_FLAGS_PDC) && NT_STATUS_IS_OK(nt_status) )
 
517
                saf_store( cli->server_domain, cli->desthost );
 
518
 
 
519
        SAFE_FREE(server_name);
 
520
        if (!NT_STATUS_IS_OK(nt_status)) {
 
521
                d_fprintf(stderr, "Connection failed: %s\n",
 
522
                          nt_errstr(nt_status));
 
523
                cli = NULL;
 
524
        } else if (c->opt_request_timeout) {
 
525
                cli_set_timeout(cli, c->opt_request_timeout * 1000);
 
526
        }
 
527
 
 
528
done:
 
529
        if (pcli != NULL) {
 
530
                *pcli = cli;
 
531
        }
 
532
        return nt_status;
 
533
}
 
534
 
 
535
/****************************************************************************
 
536
****************************************************************************/
 
537
 
 
538
const char *net_prompt_pass(struct net_context *c, const char *user)
 
539
{
 
540
        char *prompt = NULL;
 
541
        const char *pass = NULL;
 
542
 
 
543
        if (c->opt_password) {
 
544
                return c->opt_password;
 
545
        }
 
546
 
 
547
        if (c->opt_machine_pass) {
 
548
                return NULL;
 
549
        }
 
550
 
 
551
        if (c->opt_kerberos && !c->opt_user_specified) {
 
552
                return NULL;
 
553
        }
 
554
 
 
555
        if (asprintf(&prompt, "Enter %s's password:", user) == -1) {
 
556
                return NULL;
 
557
        }
 
558
 
 
559
        pass = getpass(prompt);
 
560
        SAFE_FREE(prompt);
 
561
 
 
562
        return pass;
 
563
}
 
564
 
 
565
int net_run_function(struct net_context *c, int argc, const char **argv,
 
566
                      const char *whoami, struct functable *table)
 
567
{
 
568
        int i;
 
569
 
 
570
        if (argc != 0) {
 
571
                for (i=0; table[i].funcname != NULL; i++) {
 
572
                        if (StrCaseCmp(argv[0], table[i].funcname) == 0)
 
573
                                return table[i].fn(c, argc-1, argv+1);
 
574
                }
 
575
        }
 
576
 
 
577
        if (c->display_usage == false) {
 
578
                d_fprintf(stderr, "Invalid command: %s %s\n", whoami,
 
579
                          (argc > 0)?argv[0]:"");
 
580
        }
 
581
        d_printf("Usage:\n");
 
582
        for (i=0; table[i].funcname != NULL; i++) {
 
583
                if(c->display_usage == false)
 
584
                        d_printf("%s %-15s %s\n", whoami, table[i].funcname,
 
585
                                 table[i].description);
 
586
                else
 
587
                        d_printf("%s\n", table[i].usage);
 
588
        }
 
589
 
 
590
        return c->display_usage?0:-1;
 
591
}
 
592
 
 
593
void net_display_usage_from_functable(struct functable *table)
 
594
{
 
595
        int i;
 
596
        for (i=0; table[i].funcname != NULL; i++) {
 
597
                d_printf("%s\n", table[i].usage);
 
598
        }
 
599
}
 
600
 
 
601
const char *net_share_type_str(int num_type)
 
602
{
 
603
        switch(num_type) {
 
604
                case 0: return "Disk";
 
605
                case 1: return "Print";
 
606
                case 2: return "Dev";
 
607
                case 3: return "IPC";
 
608
                default: return "Unknown";
 
609
        }
 
610
}
 
611
 
 
612
NTSTATUS net_scan_dc(struct net_context *c,
 
613
                     struct cli_state *cli,
 
614
                     struct net_dc_info *dc_info)
 
615
{
 
616
        TALLOC_CTX *mem_ctx = talloc_tos();
 
617
        struct rpc_pipe_client *dssetup_pipe = NULL;
 
618
        union dssetup_DsRoleInfo info;
 
619
        NTSTATUS status;
 
620
 
 
621
        ZERO_STRUCTP(dc_info);
 
622
 
 
623
        status = cli_rpc_pipe_open_noauth(cli, &ndr_table_dssetup.syntax_id,
 
624
                                          &dssetup_pipe);
 
625
        if (!NT_STATUS_IS_OK(status)) {
 
626
                return status;
 
627
        }
 
628
 
 
629
        status = rpccli_dssetup_DsRoleGetPrimaryDomainInformation(dssetup_pipe, mem_ctx,
 
630
                                                                  DS_ROLE_BASIC_INFORMATION,
 
631
                                                                  &info,
 
632
                                                                  NULL);
 
633
        TALLOC_FREE(dssetup_pipe);
 
634
 
 
635
        if (!NT_STATUS_IS_OK(status)) {
 
636
                return status;
 
637
        }
 
638
 
 
639
        dc_info->is_dc  = (info.basic.role & (DS_ROLE_PRIMARY_DC|DS_ROLE_BACKUP_DC));
 
640
        dc_info->is_pdc = (info.basic.role & DS_ROLE_PRIMARY_DC);
 
641
        dc_info->is_ad  = (info.basic.flags & DS_ROLE_PRIMARY_DS_RUNNING);
 
642
        dc_info->is_mixed_mode = (info.basic.flags & DS_ROLE_PRIMARY_DS_MIXED_MODE);
 
643
        dc_info->netbios_domain_name = talloc_strdup(mem_ctx, info.basic.domain);
 
644
        dc_info->dns_domain_name = talloc_strdup(mem_ctx, info.basic.dns_domain);
 
645
        dc_info->forest_name = talloc_strdup(mem_ctx, info.basic.forest);
 
646
 
 
647
        return NT_STATUS_OK;
 
648
}