00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "includes.h"
00023 #include "utils/net.h"
00024
00025 static NTSTATUS rpc_sh_info(TALLOC_CTX *mem_ctx, struct rpc_sh_ctx *ctx,
00026 struct rpc_pipe_client *pipe_hnd,
00027 int argc, const char **argv)
00028 {
00029 return rpc_info_internals(ctx->domain_sid, ctx->domain_name,
00030 ctx->cli, pipe_hnd, mem_ctx,
00031 argc, argv);
00032 }
00033
00034 static struct rpc_sh_ctx *this_ctx;
00035
00036 static char **completion_fn(const char *text, int start, int end)
00037 {
00038 char **cmds = NULL;
00039 int n_cmds = 0;
00040 struct rpc_sh_cmd *c;
00041
00042 if (start != 0) {
00043 return NULL;
00044 }
00045
00046 ADD_TO_ARRAY(NULL, char *, SMB_STRDUP(text), &cmds, &n_cmds);
00047
00048 for (c = this_ctx->cmds; c->name != NULL; c++) {
00049 BOOL match = (strncmp(text, c->name, strlen(text)) == 0);
00050
00051 if (match) {
00052 ADD_TO_ARRAY(NULL, char *, SMB_STRDUP(c->name),
00053 &cmds, &n_cmds);
00054 }
00055 }
00056
00057 if (n_cmds == 2) {
00058 SAFE_FREE(cmds[0]);
00059 cmds[0] = cmds[1];
00060 n_cmds -= 1;
00061 }
00062
00063 ADD_TO_ARRAY(NULL, char *, NULL, &cmds, &n_cmds);
00064 return cmds;
00065 }
00066
00067 static NTSTATUS net_sh_run(struct rpc_sh_ctx *ctx, struct rpc_sh_cmd *cmd,
00068 int argc, const char **argv)
00069 {
00070 TALLOC_CTX *mem_ctx;
00071 struct rpc_pipe_client *pipe_hnd;
00072 NTSTATUS status;
00073
00074 mem_ctx = talloc_new(ctx);
00075 if (mem_ctx == NULL) {
00076 d_fprintf(stderr, "talloc_new failed\n");
00077 return NT_STATUS_NO_MEMORY;
00078 }
00079
00080 pipe_hnd = cli_rpc_pipe_open_noauth(ctx->cli, cmd->pipe_idx, &status);
00081 if (pipe_hnd == NULL) {
00082 d_fprintf(stderr, "Could not open pipe: %s\n",
00083 nt_errstr(status));
00084 return status;
00085 }
00086
00087 status = cmd->fn(mem_ctx, ctx, pipe_hnd, argc, argv);
00088
00089 cli_rpc_pipe_close(pipe_hnd);
00090
00091 talloc_destroy(mem_ctx);
00092
00093 return status;
00094 }
00095
00096 static BOOL net_sh_process(struct rpc_sh_ctx *ctx,
00097 int argc, const char **argv)
00098 {
00099 struct rpc_sh_cmd *c;
00100 struct rpc_sh_ctx *new_ctx;
00101 NTSTATUS status;
00102
00103 if (argc == 0) {
00104 return True;
00105 }
00106
00107 if (ctx == this_ctx) {
00108
00109
00110 if (strequal(argv[0], "..") &&
00111 (this_ctx->parent != NULL)) {
00112 new_ctx = this_ctx->parent;
00113 TALLOC_FREE(this_ctx);
00114 this_ctx = new_ctx;
00115 return True;
00116 }
00117 }
00118
00119 if (strequal(argv[0], "exit") || strequal(argv[0], "quit")) {
00120 return False;
00121 }
00122
00123 if (strequal(argv[0], "help") || strequal(argv[0], "?")) {
00124 for (c = ctx->cmds; c->name != NULL; c++) {
00125 if (ctx != this_ctx) {
00126 d_printf("%s ", ctx->whoami);
00127 }
00128 d_printf("%-15s %s\n", c->name, c->help);
00129 }
00130 return True;
00131 }
00132
00133 for (c = ctx->cmds; c->name != NULL; c++) {
00134 if (strequal(c->name, argv[0])) {
00135 break;
00136 }
00137 }
00138
00139 if (c->name == NULL) {
00140
00141 d_fprintf(stderr, "%s: unknown cmd\n", argv[0]);
00142 return True;
00143 }
00144
00145 new_ctx = TALLOC_P(ctx, struct rpc_sh_ctx);
00146 if (new_ctx == NULL) {
00147 d_fprintf(stderr, "talloc failed\n");
00148 return False;
00149 }
00150 new_ctx->cli = ctx->cli;
00151 new_ctx->whoami = talloc_asprintf(new_ctx, "%s %s",
00152 ctx->whoami, c->name);
00153 new_ctx->thiscmd = talloc_strdup(new_ctx, c->name);
00154
00155 if (c->sub != NULL) {
00156 new_ctx->cmds = c->sub(new_ctx, ctx);
00157 } else {
00158 new_ctx->cmds = NULL;
00159 }
00160
00161 new_ctx->parent = ctx;
00162 new_ctx->domain_name = ctx->domain_name;
00163 new_ctx->domain_sid = ctx->domain_sid;
00164
00165 argc -= 1;
00166 argv += 1;
00167
00168 if (c->sub != NULL) {
00169 if (argc == 0) {
00170 this_ctx = new_ctx;
00171 return True;
00172 }
00173 return net_sh_process(new_ctx, argc, argv);
00174 }
00175
00176 status = net_sh_run(new_ctx, c, argc, argv);
00177
00178 if (!NT_STATUS_IS_OK(status)) {
00179 d_fprintf(stderr, "%s failed: %s\n", new_ctx->whoami,
00180 nt_errstr(status));
00181 }
00182
00183 return True;
00184 }
00185
00186 static struct rpc_sh_cmd sh_cmds[6] = {
00187
00188 { "info", NULL, PI_SAMR, rpc_sh_info,
00189 "Print information about the domain connected to" },
00190
00191 { "rights", net_rpc_rights_cmds, 0, NULL,
00192 "List/Grant/Revoke user rights" },
00193
00194 { "share", net_rpc_share_cmds, 0, NULL,
00195 "List/Add/Remove etc shares" },
00196
00197 { "user", net_rpc_user_cmds, 0, NULL,
00198 "List/Add/Remove user info" },
00199
00200 { "account", net_rpc_acct_cmds, 0, NULL,
00201 "Show/Change account policy settings" },
00202
00203 { NULL, NULL, 0, NULL, NULL }
00204 };
00205
00206 int net_rpc_shell(int argc, const char **argv)
00207 {
00208 NTSTATUS status;
00209 struct rpc_sh_ctx *ctx;
00210
00211 if (argc != 0) {
00212 d_fprintf(stderr, "usage: net rpc shell\n");
00213 return -1;
00214 }
00215
00216 ctx = TALLOC_P(NULL, struct rpc_sh_ctx);
00217 if (ctx == NULL) {
00218 d_fprintf(stderr, "talloc failed\n");
00219 return -1;
00220 }
00221
00222 ctx->cli = net_make_ipc_connection(0);
00223 if (ctx->cli == NULL) {
00224 d_fprintf(stderr, "Could not open connection\n");
00225 return -1;
00226 }
00227
00228 ctx->cmds = sh_cmds;
00229 ctx->whoami = "net rpc";
00230 ctx->parent = NULL;
00231
00232 status = net_get_remote_domain_sid(ctx->cli, ctx, &ctx->domain_sid,
00233 &ctx->domain_name);
00234 if (!NT_STATUS_IS_OK(status)) {
00235 return -1;
00236 }
00237
00238 d_printf("Talking to domain %s (%s)\n", ctx->domain_name,
00239 sid_string_static(ctx->domain_sid));
00240
00241 this_ctx = ctx;
00242
00243 while(1) {
00244 char *prompt;
00245 char *line;
00246 int ret;
00247
00248 asprintf(&prompt, "%s> ", this_ctx->whoami);
00249
00250 line = smb_readline(prompt, NULL, completion_fn);
00251 SAFE_FREE(prompt);
00252
00253 if (line == NULL) {
00254 break;
00255 }
00256
00257 ret = poptParseArgvString(line, &argc, &argv);
00258 if (ret == POPT_ERROR_NOARG) {
00259 continue;
00260 }
00261 if (ret != 0) {
00262 d_fprintf(stderr, "cmdline invalid: %s\n",
00263 poptStrerror(ret));
00264 return False;
00265 }
00266
00267 if ((line[0] != '\n') &&
00268 (!net_sh_process(this_ctx, argc, argv))) {
00269 break;
00270 }
00271 }
00272
00273 cli_shutdown(ctx->cli);
00274
00275 TALLOC_FREE(ctx);
00276
00277 return 0;
00278 }