~vcs-imports/samba/main

« back to all changes in this revision

Viewing changes to source/utils/net_rpc_shell.c

  • Committer: jerry
  • Date: 2006-07-14 21:48:39 UTC
  • Revision ID: vcs-imports@canonical.com-20060714214839-586d8c489a8fcead
gutting trunk to move to svn:externals

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 *  Unix SMB/CIFS implementation.
3
 
 *  Shell around net rpc subcommands
4
 
 *  Copyright (C) Volker Lendecke 2006
5
 
 *
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 2 of the License, or
9
 
 *  (at your option) any later version.
10
 
 *
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.
15
 
 *
16
 
 *  You should have received a copy of the GNU General Public License
17
 
 *  along with this program; if not, write to the Free Software
18
 
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
 
 */
20
 
 
21
 
 
22
 
#include "includes.h"
23
 
#include "utils/net.h"
24
 
 
25
 
static NTSTATUS rpc_sh_info(TALLOC_CTX *mem_ctx, struct rpc_sh_ctx *ctx,
26
 
                            struct rpc_pipe_client *pipe_hnd,
27
 
                            int argc, const char **argv)
28
 
{
29
 
        return rpc_info_internals(ctx->domain_sid, ctx->domain_name,
30
 
                                  ctx->cli, pipe_hnd, mem_ctx,
31
 
                                  argc, argv);
32
 
}
33
 
 
34
 
static struct rpc_sh_ctx *this_ctx;
35
 
 
36
 
static char **completion_fn(const char *text, int start, int end)
37
 
{
38
 
        char **cmds = NULL;
39
 
        int n_cmds = 0;
40
 
        struct rpc_sh_cmd *c;
41
 
 
42
 
        if (start != 0) {
43
 
                return NULL;
44
 
        }
45
 
 
46
 
        ADD_TO_ARRAY(NULL, char *, SMB_STRDUP(text), &cmds, &n_cmds);
47
 
 
48
 
        for (c = this_ctx->cmds; c->name != NULL; c++) {
49
 
                BOOL match = (strncmp(text, c->name, strlen(text)) == 0);
50
 
 
51
 
                if (match) {
52
 
                        ADD_TO_ARRAY(NULL, char *, SMB_STRDUP(c->name),
53
 
                                     &cmds, &n_cmds);
54
 
                }
55
 
        }
56
 
 
57
 
        if (n_cmds == 2) {
58
 
                SAFE_FREE(cmds[0]);
59
 
                cmds[0] = cmds[1];
60
 
                n_cmds -= 1;
61
 
        }
62
 
 
63
 
        ADD_TO_ARRAY(NULL, char *, NULL, &cmds, &n_cmds);
64
 
        return cmds;
65
 
}
66
 
 
67
 
static NTSTATUS net_sh_run(struct rpc_sh_ctx *ctx, struct rpc_sh_cmd *cmd,
68
 
                           int argc, const char **argv)
69
 
{
70
 
        TALLOC_CTX *mem_ctx;
71
 
        struct rpc_pipe_client *pipe_hnd;
72
 
        NTSTATUS status;
73
 
 
74
 
        mem_ctx = talloc_new(ctx);
75
 
        if (mem_ctx == NULL) {
76
 
                d_fprintf(stderr, "talloc_new failed\n");
77
 
                return NT_STATUS_NO_MEMORY;
78
 
        }
79
 
 
80
 
        pipe_hnd = cli_rpc_pipe_open_noauth(ctx->cli, cmd->pipe_idx, &status);
81
 
        if (pipe_hnd == NULL) {
82
 
                d_fprintf(stderr, "Could not open pipe: %s\n",
83
 
                          nt_errstr(status));
84
 
                return status;
85
 
        }
86
 
 
87
 
        status = cmd->fn(mem_ctx, ctx, pipe_hnd, argc, argv);
88
 
 
89
 
        cli_rpc_pipe_close(pipe_hnd);
90
 
 
91
 
        talloc_destroy(mem_ctx);
92
 
 
93
 
        return status;
94
 
}
95
 
 
96
 
static BOOL net_sh_process(struct rpc_sh_ctx *ctx,
97
 
                           int argc, const char **argv)
98
 
{
99
 
        struct rpc_sh_cmd *c;
100
 
        struct rpc_sh_ctx *new_ctx;
101
 
        NTSTATUS status;
102
 
 
103
 
        if (argc == 0) {
104
 
                return True;
105
 
        }
106
 
 
107
 
        if (ctx == this_ctx) {
108
 
 
109
 
                /* We've been called from the cmd line */
110
 
                if (strequal(argv[0], "..") &&
111
 
                    (this_ctx->parent != NULL)) {
112
 
                        new_ctx = this_ctx->parent;
113
 
                        TALLOC_FREE(this_ctx);
114
 
                        this_ctx = new_ctx;
115
 
                        return True;
116
 
                }
117
 
        }
118
 
 
119
 
        if (strequal(argv[0], "exit") || strequal(argv[0], "quit")) {
120
 
                return False;
121
 
        }
122
 
 
123
 
        if (strequal(argv[0], "help") || strequal(argv[0], "?")) {
124
 
                for (c = ctx->cmds; c->name != NULL; c++) {
125
 
                        if (ctx != this_ctx) {
126
 
                                d_printf("%s ", ctx->whoami);
127
 
                        }
128
 
                        d_printf("%-15s %s\n", c->name, c->help);
129
 
                }
130
 
                return True;
131
 
        }
132
 
 
133
 
        for (c = ctx->cmds; c->name != NULL; c++) {
134
 
                if (strequal(c->name, argv[0])) {
135
 
                        break;
136
 
                }
137
 
        }
138
 
 
139
 
        if (c->name == NULL) {
140
 
                /* None found */
141
 
                d_fprintf(stderr, "%s: unknown cmd\n", argv[0]);
142
 
                return True;
143
 
        }
144
 
 
145
 
        new_ctx = TALLOC_P(ctx, struct rpc_sh_ctx);
146
 
        if (new_ctx == NULL) {
147
 
                d_fprintf(stderr, "talloc failed\n");
148
 
                return False;
149
 
        }
150
 
        new_ctx->cli = ctx->cli;
151
 
        new_ctx->whoami = talloc_asprintf(new_ctx, "%s %s",
152
 
                                          ctx->whoami, c->name);
153
 
        new_ctx->thiscmd = talloc_strdup(new_ctx, c->name);
154
 
 
155
 
        if (c->sub != NULL) {
156
 
                new_ctx->cmds = c->sub(new_ctx, ctx);
157
 
        } else {
158
 
                new_ctx->cmds = NULL;
159
 
        }
160
 
 
161
 
        new_ctx->parent = ctx;
162
 
        new_ctx->domain_name = ctx->domain_name;
163
 
        new_ctx->domain_sid = ctx->domain_sid;
164
 
 
165
 
        argc -= 1;
166
 
        argv += 1;
167
 
 
168
 
        if (c->sub != NULL) {
169
 
                if (argc == 0) {
170
 
                        this_ctx = new_ctx;
171
 
                        return True;
172
 
                }
173
 
                return net_sh_process(new_ctx, argc, argv);
174
 
        }
175
 
 
176
 
        status = net_sh_run(new_ctx, c, argc, argv);
177
 
 
178
 
        if (!NT_STATUS_IS_OK(status)) {
179
 
                d_fprintf(stderr, "%s failed: %s\n", new_ctx->whoami,
180
 
                          nt_errstr(status));
181
 
        }
182
 
 
183
 
        return True;
184
 
}
185
 
 
186
 
static struct rpc_sh_cmd sh_cmds[6] = {
187
 
 
188
 
        { "info", NULL, PI_SAMR, rpc_sh_info,
189
 
          "Print information about the domain connected to" },
190
 
 
191
 
        { "rights", net_rpc_rights_cmds, 0, NULL,
192
 
          "List/Grant/Revoke user rights" },
193
 
 
194
 
        { "share", net_rpc_share_cmds, 0, NULL,
195
 
          "List/Add/Remove etc shares" },
196
 
 
197
 
        { "user", net_rpc_user_cmds, 0, NULL,
198
 
          "List/Add/Remove user info" },
199
 
 
200
 
        { "account", net_rpc_acct_cmds, 0, NULL,
201
 
          "Show/Change account policy settings" },
202
 
 
203
 
        { NULL, NULL, 0, NULL, NULL }
204
 
};
205
 
 
206
 
int net_rpc_shell(int argc, const char **argv)
207
 
{
208
 
        NTSTATUS status;
209
 
        struct rpc_sh_ctx *ctx;
210
 
 
211
 
        if (argc != 0) {
212
 
                d_fprintf(stderr, "usage: net rpc shell\n");
213
 
                return -1;
214
 
        }
215
 
 
216
 
        ctx = TALLOC_P(NULL, struct rpc_sh_ctx);
217
 
        if (ctx == NULL) {
218
 
                d_fprintf(stderr, "talloc failed\n");
219
 
                return -1;
220
 
        }
221
 
 
222
 
        ctx->cli = net_make_ipc_connection(0);
223
 
        if (ctx->cli == NULL) {
224
 
                d_fprintf(stderr, "Could not open connection\n");
225
 
                return -1;
226
 
        }
227
 
 
228
 
        ctx->cmds = sh_cmds;
229
 
        ctx->whoami = "net rpc";
230
 
        ctx->parent = NULL;
231
 
 
232
 
        status = net_get_remote_domain_sid(ctx->cli, ctx, &ctx->domain_sid,
233
 
                                           &ctx->domain_name);
234
 
        if (!NT_STATUS_IS_OK(status)) {
235
 
                return -1;
236
 
        }
237
 
 
238
 
        d_printf("Talking to domain %s (%s)\n", ctx->domain_name,
239
 
                 sid_string_static(ctx->domain_sid));
240
 
        
241
 
        this_ctx = ctx;
242
 
 
243
 
        while(1) {
244
 
                char *prompt;
245
 
                char *line;
246
 
                int ret;
247
 
 
248
 
                asprintf(&prompt, "%s> ", this_ctx->whoami);
249
 
 
250
 
                line = smb_readline(prompt, NULL, completion_fn);
251
 
                SAFE_FREE(prompt);
252
 
 
253
 
                if (line == NULL) {
254
 
                        break;
255
 
                }
256
 
 
257
 
                ret = poptParseArgvString(line, &argc, &argv);
258
 
                if (ret == POPT_ERROR_NOARG) {
259
 
                        continue;
260
 
                }
261
 
                if (ret != 0) {
262
 
                        d_fprintf(stderr, "cmdline invalid: %s\n",
263
 
                                  poptStrerror(ret));
264
 
                        return False;
265
 
                }
266
 
 
267
 
                if ((line[0] != '\n') &&
268
 
                    (!net_sh_process(this_ctx, argc, argv))) {
269
 
                        break;
270
 
                }
271
 
        }
272
 
 
273
 
        cli_shutdown(ctx->cli);
274
 
 
275
 
        TALLOC_FREE(ctx);
276
 
 
277
 
        return 0;
278
 
}