2 * Unix SMB/CIFS implementation.
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/>.
21 #include "../libcli/auth/netlogon_creds_cli.h"
22 #include "lib/netapi/netapi.h"
23 #include "lib/netapi/netapi_private.h"
26 #include "source3/param/loadparm.h"
27 #include "lib/param/param.h"
28 #include "auth/gensec/gensec.h"
30 struct libnetapi_ctx *stat_ctx = NULL;
31 static bool libnetapi_initialized = false;
33 /****************************************************************
34 ****************************************************************/
36 static NET_API_STATUS libnetapi_init_private_context(struct libnetapi_ctx *ctx)
38 struct libnetapi_private_ctx *priv;
41 return W_ERROR_V(WERR_INVALID_PARAMETER);
44 priv = talloc_zero(ctx, struct libnetapi_private_ctx);
46 return W_ERROR_V(WERR_NOT_ENOUGH_MEMORY);
49 ctx->private_data = priv;
51 return NET_API_STATUS_SUCCESS;
54 /****************************************************************
55 Create a libnetapi context, for use in non-Samba applications. This
56 loads the smb.conf file and sets the debug level to 0, so that
57 applications are not flooded with debug logs at level 10, when they
58 were not expecting it.
59 ****************************************************************/
61 NET_API_STATUS libnetapi_init(struct libnetapi_ctx **context)
65 if (stat_ctx && libnetapi_initialized) {
67 return NET_API_STATUS_SUCCESS;
71 talloc_enable_leak_report();
73 frame = talloc_stackframe();
75 /* When libnetapi is invoked from an application, it does not
76 * want to be swamped with level 10 debug messages, even if
77 * this has been set for the server in smb.conf */
78 lp_set_cmdline("log level", "0");
79 setup_logging("libnetapi", DEBUG_STDERR);
81 if (!lp_load_global(get_dyn_CONFIGFILE())) {
83 fprintf(stderr, "error loading %s\n", get_dyn_CONFIGFILE() );
84 return W_ERROR_V(WERR_GEN_FAILURE);
90 BlockSignals(True, SIGPIPE);
92 ret = libnetapi_net_init(context);
97 /****************************************************************
98 Create a libnetapi context, for use inside the 'net' binary.
100 As we know net has already loaded the smb.conf file, and set the debug
101 level etc, this avoids doing so again (which causes trouble with -d on
103 ****************************************************************/
105 NET_API_STATUS libnetapi_net_init(struct libnetapi_ctx **context)
107 NET_API_STATUS status;
108 struct libnetapi_ctx *ctx = NULL;
109 TALLOC_CTX *frame = talloc_stackframe();
110 struct loadparm_context *lp_ctx = NULL;
112 ctx = talloc_zero(frame, struct libnetapi_ctx);
115 return W_ERROR_V(WERR_NOT_ENOUGH_MEMORY);
118 ctx->creds = cli_credentials_init(ctx);
119 if (ctx->creds == NULL) {
121 return W_ERROR_V(WERR_NOT_ENOUGH_MEMORY);
124 lp_ctx = loadparm_init_s3(frame, loadparm_s3_helpers());
125 if (lp_ctx == NULL) {
127 return W_ERROR_V(WERR_NOT_ENOUGH_MEMORY);
130 BlockSignals(True, SIGPIPE);
132 /* Ignore return code, as we might not have a smb.conf */
133 (void)cli_credentials_guess(ctx->creds, lp_ctx);
135 status = libnetapi_init_private_context(ctx);
141 libnetapi_initialized = true;
143 talloc_steal(NULL, ctx);
144 *context = stat_ctx = ctx;
147 return NET_API_STATUS_SUCCESS;
150 /****************************************************************
151 Return the static libnetapi context
152 ****************************************************************/
154 NET_API_STATUS libnetapi_getctx(struct libnetapi_ctx **ctx)
158 return NET_API_STATUS_SUCCESS;
161 return libnetapi_init(ctx);
164 /****************************************************************
165 Free the static libnetapi context
166 ****************************************************************/
168 NET_API_STATUS libnetapi_free(struct libnetapi_ctx *ctx)
173 return NET_API_STATUS_SUCCESS;
176 frame = talloc_stackframe();
177 libnetapi_samr_free(ctx);
179 libnetapi_shutdown_cm(ctx);
187 netlogon_creds_cli_close_global_db();
189 if (ctx == stat_ctx) {
197 return NET_API_STATUS_SUCCESS;
200 /****************************************************************
201 Override the current log level for libnetapi
202 ****************************************************************/
204 NET_API_STATUS libnetapi_set_debuglevel(struct libnetapi_ctx *ctx,
205 const char *debuglevel)
207 TALLOC_CTX *frame = talloc_stackframe();
208 ctx->debuglevel = talloc_strdup(ctx, debuglevel);
210 if (!lp_set_cmdline("log level", debuglevel)) {
212 return W_ERROR_V(WERR_GEN_FAILURE);
215 return NET_API_STATUS_SUCCESS;
218 /****************************************************************
219 ****************************************************************/
221 NET_API_STATUS libnetapi_set_logfile(struct libnetapi_ctx *ctx,
224 TALLOC_CTX *frame = talloc_stackframe();
225 ctx->logfile = talloc_strdup(ctx, logfile);
227 if (!lp_set_cmdline("log file", logfile)) {
229 return W_ERROR_V(WERR_GEN_FAILURE);
231 debug_set_logfile(logfile);
232 setup_logging("libnetapi", DEBUG_FILE);
234 return NET_API_STATUS_SUCCESS;
237 /****************************************************************
238 ****************************************************************/
240 NET_API_STATUS libnetapi_get_debuglevel(struct libnetapi_ctx *ctx,
243 *debuglevel = ctx->debuglevel;
244 return NET_API_STATUS_SUCCESS;
247 /****************************************************************
248 ****************************************************************/
251 * @brief Get the username of the libnet context
253 * @param[in] ctx The netapi context
255 * @param[in] username A pointer to hold the username.
257 * @return 0 on success, an werror code otherwise.
259 NET_API_STATUS libnetapi_get_username(struct libnetapi_ctx *ctx,
260 const char **username)
263 return W_ERROR_V(WERR_INVALID_PARAMETER);
266 if (username != NULL) {
267 *username = cli_credentials_get_username(ctx->creds);
270 return NET_API_STATUS_SUCCESS;
274 * @brief Get the password of the libnet context
276 * @param[in] ctx The netapi context
278 * @param[in] password A pointer to hold the password.
280 * @return 0 on success, an werror code otherwise.
282 NET_API_STATUS libnetapi_get_password(struct libnetapi_ctx *ctx,
283 const char **password)
286 return W_ERROR_V(WERR_INVALID_PARAMETER);
289 if (password != NULL) {
290 *password = cli_credentials_get_password(ctx->creds);
293 return NET_API_STATUS_SUCCESS;
296 NET_API_STATUS libnetapi_set_username(struct libnetapi_ctx *ctx,
297 const char *username)
299 if (ctx == NULL || username == NULL) {
300 return W_ERROR_V(WERR_INVALID_PARAMETER);
303 cli_credentials_parse_string(ctx->creds, username, CRED_SPECIFIED);
305 return NET_API_STATUS_SUCCESS;
308 NET_API_STATUS libnetapi_set_password(struct libnetapi_ctx *ctx,
309 const char *password)
313 if (ctx == NULL || password == NULL) {
314 return W_ERROR_V(WERR_INVALID_PARAMETER);
317 ok = cli_credentials_set_password(ctx->creds, password, CRED_SPECIFIED);
319 return W_ERROR_V(WERR_INTERNAL_ERROR);
322 return NET_API_STATUS_SUCCESS;
325 NET_API_STATUS libnetapi_set_workgroup(struct libnetapi_ctx *ctx,
326 const char *workgroup)
330 ok = cli_credentials_set_domain(ctx->creds, workgroup, CRED_SPECIFIED);
332 return W_ERROR_V(WERR_INTERNAL_ERROR);
335 return NET_API_STATUS_SUCCESS;
339 * @brief Set the cli_credentials to be used in the netapi context
341 * @param[in] ctx The netapi context
343 * @param[in] creds The cli_credentials which should be used by netapi.
345 * @return 0 on success, an werror code otherwise.
347 NET_API_STATUS libnetapi_set_creds(struct libnetapi_ctx *ctx,
348 struct cli_credentials *creds)
350 if (ctx == NULL || creds == NULL) {
351 return W_ERROR_V(WERR_INVALID_PARAMETER);
356 return NET_API_STATUS_SUCCESS;
359 /****************************************************************
360 ****************************************************************/
362 NET_API_STATUS libnetapi_set_use_kerberos(struct libnetapi_ctx *ctx)
364 cli_credentials_set_kerberos_state(ctx->creds,
365 CRED_USE_KERBEROS_REQUIRED,
368 return NET_API_STATUS_SUCCESS;
371 /****************************************************************
372 ****************************************************************/
374 NET_API_STATUS libnetapi_get_use_kerberos(struct libnetapi_ctx *ctx,
377 enum credentials_use_kerberos creds_use_kerberos;
381 creds_use_kerberos = cli_credentials_get_kerberos_state(ctx->creds);
382 if (creds_use_kerberos > CRED_USE_KERBEROS_DESIRED) {
386 return NET_API_STATUS_SUCCESS;
389 /****************************************************************
390 ****************************************************************/
392 NET_API_STATUS libnetapi_set_use_ccache(struct libnetapi_ctx *ctx)
394 uint32_t gensec_features;
396 gensec_features = cli_credentials_get_gensec_features(ctx->creds);
397 gensec_features |= GENSEC_FEATURE_NTLM_CCACHE;
398 cli_credentials_set_gensec_features(ctx->creds,
402 return NET_API_STATUS_SUCCESS;
405 /****************************************************************
406 Return a libnetapi error as a string, caller must free with NetApiBufferFree
407 ****************************************************************/
409 char *libnetapi_errstr(NET_API_STATUS status)
411 TALLOC_CTX *frame = talloc_stackframe();
413 if (status & 0xc0000000) {
414 ret = talloc_strdup(NULL,
415 get_friendly_nt_error_msg(NT_STATUS(status)));
417 ret = talloc_strdup(NULL,
418 get_friendly_werror_msg(W_ERROR(status)));
424 /****************************************************************
425 ****************************************************************/
427 NET_API_STATUS libnetapi_set_error_string(struct libnetapi_ctx *ctx,
428 const char *format, ...)
432 TALLOC_FREE(ctx->error_string);
434 va_start(args, format);
435 ctx->error_string = talloc_vasprintf(ctx, format, args);
438 if (!ctx->error_string) {
439 return W_ERROR_V(WERR_NOT_ENOUGH_MEMORY);
441 return NET_API_STATUS_SUCCESS;
444 /****************************************************************
445 Return a libnetapi_errstr(), caller must free with NetApiBufferFree
446 ****************************************************************/
448 char *libnetapi_get_error_string(struct libnetapi_ctx *ctx,
449 NET_API_STATUS status_in)
451 NET_API_STATUS status;
452 struct libnetapi_ctx *tmp_ctx = ctx;
455 status = libnetapi_getctx(&tmp_ctx);
461 if (tmp_ctx->error_string) {
462 return talloc_strdup(NULL, tmp_ctx->error_string);
465 return libnetapi_errstr(status_in);
468 /****************************************************************
469 ****************************************************************/
471 NET_API_STATUS NetApiBufferAllocate(uint32_t byte_count,
477 return W_ERROR_V(WERR_INSUFFICIENT_BUFFER);
480 if (byte_count == 0) {
484 buf = talloc_size(NULL, byte_count);
486 return W_ERROR_V(WERR_NOT_ENOUGH_MEMORY);
492 return NET_API_STATUS_SUCCESS;
495 /****************************************************************
496 ****************************************************************/
498 NET_API_STATUS NetApiBufferFree(void *buffer)
501 return W_ERROR_V(WERR_INSUFFICIENT_BUFFER);
506 return NET_API_STATUS_SUCCESS;