ctdb-scripts: Don't set arp_filter=1 by default in 10.interface
[Samba.git] / source3 / lib / netapi / netapi.c
blobdff9f7de35b90df90931bfcc422fde36516371ed
1 /*
2 * Unix SMB/CIFS implementation.
3 * NetApi Support
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 #include "includes.h"
21 #include "../libcli/auth/netlogon_creds_cli.h"
22 #include "lib/netapi/netapi.h"
23 #include "lib/netapi/netapi_private.h"
24 #include "secrets.h"
25 #include "source3/param/loadparm.h"
26 #include "lib/param/param.h"
27 #include "auth/gensec/gensec.h"
29 struct libnetapi_ctx *stat_ctx = NULL;
30 static bool libnetapi_initialized = false;
32 /****************************************************************
33 ****************************************************************/
35 static NET_API_STATUS libnetapi_init_private_context(struct libnetapi_ctx *ctx)
37 struct libnetapi_private_ctx *priv;
39 if (!ctx) {
40 return W_ERROR_V(WERR_INVALID_PARAMETER);
43 priv = talloc_zero(ctx, struct libnetapi_private_ctx);
44 if (!priv) {
45 return W_ERROR_V(WERR_NOT_ENOUGH_MEMORY);
48 ctx->private_data = priv;
50 return NET_API_STATUS_SUCCESS;
53 /****************************************************************
54 Create a libnetapi context, for use in non-Samba applications. This
55 loads the smb.conf file and sets the debug level to 0, so that
56 applications are not flooded with debug logs at level 10, when they
57 were not expecting it.
58 ****************************************************************/
60 NET_API_STATUS libnetapi_init(struct libnetapi_ctx **context)
62 NET_API_STATUS ret;
63 TALLOC_CTX *frame;
64 struct loadparm_context *lp_ctx = NULL;
66 if (stat_ctx && libnetapi_initialized) {
67 *context = stat_ctx;
68 return NET_API_STATUS_SUCCESS;
71 #if 0
72 talloc_enable_leak_report();
73 #endif
74 frame = talloc_stackframe();
76 lp_ctx = loadparm_init_s3(frame, loadparm_s3_helpers());
77 if (lp_ctx == NULL) {
78 TALLOC_FREE(frame);
79 return W_ERROR_V(WERR_NOT_ENOUGH_MEMORY);
82 /* When libnetapi is invoked from an application, it does not
83 * want to be swamped with level 10 debug messages, even if
84 * this has been set for the server in smb.conf */
85 lpcfg_set_cmdline(lp_ctx, "log level", "0");
86 setup_logging("libnetapi", DEBUG_STDERR);
88 if (!lp_load_global(get_dyn_CONFIGFILE())) {
89 TALLOC_FREE(frame);
90 fprintf(stderr, "error loading %s\n", get_dyn_CONFIGFILE() );
91 return W_ERROR_V(WERR_GEN_FAILURE);
94 load_interfaces();
95 reopen_logs();
97 BlockSignals(True, SIGPIPE);
99 ret = libnetapi_net_init(context, lp_ctx, NULL);
100 if (ret == NET_API_STATUS_SUCCESS) {
101 talloc_steal(*context, lp_ctx);
103 TALLOC_FREE(frame);
104 return ret;
107 /****************************************************************
108 Create a libnetapi context, for use inside the 'net' binary.
110 As we know net has already loaded the smb.conf file, and set the debug
111 level etc, this avoids doing so again (which causes trouble with -d on
112 the command line).
113 ****************************************************************/
115 NET_API_STATUS libnetapi_net_init(struct libnetapi_ctx **context,
116 struct loadparm_context *lp_ctx,
117 struct cli_credentials *creds)
119 NET_API_STATUS status;
120 struct libnetapi_ctx *ctx = NULL;
121 TALLOC_CTX *frame = NULL;
123 if (stat_ctx != NULL && libnetapi_initialized) {
124 *context = stat_ctx;
125 return NET_API_STATUS_SUCCESS;
128 frame = talloc_stackframe();
129 ctx = talloc_zero(frame, struct libnetapi_ctx);
130 if (!ctx) {
131 TALLOC_FREE(frame);
132 return W_ERROR_V(WERR_NOT_ENOUGH_MEMORY);
135 ctx->lp_ctx = lp_ctx;
137 ctx->creds = creds;
138 if (ctx->creds == NULL) {
139 ctx->creds = cli_credentials_init(ctx);
140 if (ctx->creds == NULL) {
141 TALLOC_FREE(frame);
142 return W_ERROR_V(WERR_NOT_ENOUGH_MEMORY);
144 /* Ignore return code, as we might not have a smb.conf */
145 (void)cli_credentials_guess(ctx->creds, lp_ctx);
148 BlockSignals(True, SIGPIPE);
150 status = libnetapi_init_private_context(ctx);
151 if (status != 0) {
152 TALLOC_FREE(frame);
153 return status;
156 libnetapi_initialized = true;
158 talloc_steal(NULL, ctx);
159 *context = stat_ctx = ctx;
161 TALLOC_FREE(frame);
162 return NET_API_STATUS_SUCCESS;
165 /****************************************************************
166 Return the static libnetapi context
167 ****************************************************************/
169 NET_API_STATUS libnetapi_getctx(struct libnetapi_ctx **ctx)
171 if (stat_ctx) {
172 *ctx = stat_ctx;
173 return NET_API_STATUS_SUCCESS;
176 return libnetapi_init(ctx);
179 /****************************************************************
180 Free the static libnetapi context
181 ****************************************************************/
183 NET_API_STATUS libnetapi_free(struct libnetapi_ctx *ctx)
185 TALLOC_CTX *frame;
187 if (!ctx) {
188 return NET_API_STATUS_SUCCESS;
191 frame = talloc_stackframe();
192 libnetapi_samr_free(ctx);
194 libnetapi_shutdown_cm(ctx);
196 gfree_loadparm();
197 gfree_charcnv();
198 gfree_interfaces();
200 secrets_shutdown();
202 netlogon_creds_cli_close_global_db();
204 if (ctx == stat_ctx) {
205 stat_ctx = NULL;
207 TALLOC_FREE(ctx);
209 gfree_debugsyms();
210 talloc_free(frame);
212 return NET_API_STATUS_SUCCESS;
215 /****************************************************************
216 Override the current log level for libnetapi
217 ****************************************************************/
219 NET_API_STATUS libnetapi_set_debuglevel(struct libnetapi_ctx *ctx,
220 const char *debuglevel)
222 TALLOC_CTX *frame = talloc_stackframe();
223 ctx->debuglevel = talloc_strdup(ctx, debuglevel);
225 if (!lpcfg_set_cmdline(ctx->lp_ctx, "log level", debuglevel)) {
226 TALLOC_FREE(frame);
227 return W_ERROR_V(WERR_GEN_FAILURE);
229 TALLOC_FREE(frame);
230 return NET_API_STATUS_SUCCESS;
233 /****************************************************************
234 ****************************************************************/
236 NET_API_STATUS libnetapi_set_logfile(struct libnetapi_ctx *ctx,
237 const char *logfile)
239 TALLOC_CTX *frame = talloc_stackframe();
240 ctx->logfile = talloc_strdup(ctx, logfile);
242 if (!lpcfg_set_cmdline(ctx->lp_ctx, "log file", logfile)) {
243 TALLOC_FREE(frame);
244 return W_ERROR_V(WERR_GEN_FAILURE);
246 debug_set_logfile(logfile);
247 setup_logging("libnetapi", DEBUG_FILE);
248 TALLOC_FREE(frame);
249 return NET_API_STATUS_SUCCESS;
252 /****************************************************************
253 ****************************************************************/
255 NET_API_STATUS libnetapi_get_debuglevel(struct libnetapi_ctx *ctx,
256 char **debuglevel)
258 *debuglevel = ctx->debuglevel;
259 return NET_API_STATUS_SUCCESS;
262 /****************************************************************
263 ****************************************************************/
266 * @brief Get the username of the libnet context
268 * @param[in] ctx The netapi context
270 * @param[in] username A pointer to hold the username.
272 * @return 0 on success, an werror code otherwise.
274 NET_API_STATUS libnetapi_get_username(struct libnetapi_ctx *ctx,
275 const char **username)
277 if (ctx == NULL) {
278 return W_ERROR_V(WERR_INVALID_PARAMETER);
281 if (username != NULL) {
282 *username = cli_credentials_get_username(ctx->creds);
285 return NET_API_STATUS_SUCCESS;
289 * @brief Get the password of the libnet context
291 * @param[in] ctx The netapi context
293 * @param[in] password A pointer to hold the password.
295 * @return 0 on success, an werror code otherwise.
297 NET_API_STATUS libnetapi_get_password(struct libnetapi_ctx *ctx,
298 const char **password)
300 if (ctx == NULL) {
301 return W_ERROR_V(WERR_INVALID_PARAMETER);
304 if (password != NULL) {
305 *password = cli_credentials_get_password(ctx->creds);
308 return NET_API_STATUS_SUCCESS;
311 NET_API_STATUS libnetapi_set_username(struct libnetapi_ctx *ctx,
312 const char *username)
314 if (ctx == NULL || username == NULL) {
315 return W_ERROR_V(WERR_INVALID_PARAMETER);
318 cli_credentials_parse_string(ctx->creds, username, CRED_SPECIFIED);
320 return NET_API_STATUS_SUCCESS;
323 NET_API_STATUS libnetapi_set_password(struct libnetapi_ctx *ctx,
324 const char *password)
326 bool ok;
328 if (ctx == NULL || password == NULL) {
329 return W_ERROR_V(WERR_INVALID_PARAMETER);
332 ok = cli_credentials_set_password(ctx->creds, password, CRED_SPECIFIED);
333 if (!ok) {
334 return W_ERROR_V(WERR_INTERNAL_ERROR);
337 return NET_API_STATUS_SUCCESS;
340 NET_API_STATUS libnetapi_set_workgroup(struct libnetapi_ctx *ctx,
341 const char *workgroup)
343 bool ok;
345 ok = cli_credentials_set_domain(ctx->creds, workgroup, CRED_SPECIFIED);
346 if (!ok) {
347 return W_ERROR_V(WERR_INTERNAL_ERROR);
350 return NET_API_STATUS_SUCCESS;
354 * @brief Set the cli_credentials to be used in the netapi context
356 * @param[in] ctx The netapi context
358 * @param[in] creds The cli_credentials which should be used by netapi.
360 * @return 0 on success, an werror code otherwise.
362 NET_API_STATUS libnetapi_set_creds(struct libnetapi_ctx *ctx,
363 struct cli_credentials *creds)
365 if (ctx == NULL || creds == NULL) {
366 return W_ERROR_V(WERR_INVALID_PARAMETER);
369 ctx->creds = creds;
371 return NET_API_STATUS_SUCCESS;
375 * @brief Get the credentials of the libnet context
377 * @param[in] ctx The netapi context
379 * @param[in] creds A pointer to hold the creds.
381 * @return 0 on success, an werror code otherwise.
383 NET_API_STATUS libnetapi_get_creds(struct libnetapi_ctx *ctx,
384 struct cli_credentials **creds)
386 if (ctx == NULL) {
387 return W_ERROR_V(WERR_INVALID_PARAMETER);
390 if (creds != NULL) {
391 *creds = ctx->creds;
394 return NET_API_STATUS_SUCCESS;
397 /****************************************************************
398 ****************************************************************/
400 NET_API_STATUS libnetapi_set_use_kerberos(struct libnetapi_ctx *ctx)
402 cli_credentials_set_kerberos_state(ctx->creds,
403 CRED_USE_KERBEROS_REQUIRED,
404 CRED_SPECIFIED);
406 return NET_API_STATUS_SUCCESS;
409 /****************************************************************
410 ****************************************************************/
412 NET_API_STATUS libnetapi_get_use_kerberos(struct libnetapi_ctx *ctx,
413 int *use_kerberos)
415 enum credentials_use_kerberos creds_use_kerberos;
417 *use_kerberos = 0;
419 creds_use_kerberos = cli_credentials_get_kerberos_state(ctx->creds);
420 if (creds_use_kerberos > CRED_USE_KERBEROS_DESIRED) {
421 *use_kerberos = 1;
424 return NET_API_STATUS_SUCCESS;
427 /****************************************************************
428 ****************************************************************/
430 NET_API_STATUS libnetapi_set_use_ccache(struct libnetapi_ctx *ctx)
432 cli_credentials_add_gensec_features(ctx->creds,
433 GENSEC_FEATURE_NTLM_CCACHE,
434 CRED_SPECIFIED);
436 return NET_API_STATUS_SUCCESS;
439 /****************************************************************
440 Return a libnetapi error as a string, caller must free with NetApiBufferFree
441 ****************************************************************/
443 char *libnetapi_errstr(NET_API_STATUS status)
445 TALLOC_CTX *frame = talloc_stackframe();
446 char *ret;
447 if (status & 0xc0000000) {
448 ret = talloc_strdup(NULL,
449 get_friendly_nt_error_msg(NT_STATUS(status)));
450 } else {
451 ret = talloc_strdup(NULL,
452 get_friendly_werror_msg(W_ERROR(status)));
454 TALLOC_FREE(frame);
455 return ret;
458 /****************************************************************
459 ****************************************************************/
461 NET_API_STATUS libnetapi_set_error_string(struct libnetapi_ctx *ctx,
462 const char *format, ...)
464 va_list args;
466 TALLOC_FREE(ctx->error_string);
468 va_start(args, format);
469 ctx->error_string = talloc_vasprintf(ctx, format, args);
470 va_end(args);
472 if (!ctx->error_string) {
473 return W_ERROR_V(WERR_NOT_ENOUGH_MEMORY);
475 return NET_API_STATUS_SUCCESS;
478 /****************************************************************
479 Return a libnetapi_errstr(), caller must free with NetApiBufferFree
480 ****************************************************************/
482 char *libnetapi_get_error_string(struct libnetapi_ctx *ctx,
483 NET_API_STATUS status_in)
485 NET_API_STATUS status;
486 struct libnetapi_ctx *tmp_ctx = ctx;
488 if (!tmp_ctx) {
489 status = libnetapi_getctx(&tmp_ctx);
490 if (status != 0) {
491 return NULL;
495 if (tmp_ctx->error_string) {
496 return talloc_strdup(NULL, tmp_ctx->error_string);
499 return libnetapi_errstr(status_in);
502 /****************************************************************
503 ****************************************************************/
505 NET_API_STATUS NetApiBufferAllocate(uint32_t byte_count,
506 void **buffer)
508 void *buf = NULL;
510 if (!buffer) {
511 return W_ERROR_V(WERR_INSUFFICIENT_BUFFER);
514 if (byte_count == 0) {
515 goto done;
518 buf = talloc_size(NULL, byte_count);
519 if (!buf) {
520 return W_ERROR_V(WERR_NOT_ENOUGH_MEMORY);
523 done:
524 *buffer = buf;
526 return NET_API_STATUS_SUCCESS;
529 /****************************************************************
530 ****************************************************************/
532 NET_API_STATUS NetApiBufferFree(void *buffer)
534 if (!buffer) {
535 return W_ERROR_V(WERR_INSUFFICIENT_BUFFER);
538 talloc_free(buffer);
540 return NET_API_STATUS_SUCCESS;