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 cli_credentials_guess(ctx->creds, lp_ctx);
134 status = libnetapi_init_private_context(ctx);
140 libnetapi_initialized = true;
142 talloc_steal(NULL, ctx);
143 *context = stat_ctx = ctx;
146 return NET_API_STATUS_SUCCESS;
149 /****************************************************************
150 Return the static libnetapi context
151 ****************************************************************/
153 NET_API_STATUS libnetapi_getctx(struct libnetapi_ctx **ctx)
157 return NET_API_STATUS_SUCCESS;
160 return libnetapi_init(ctx);
163 /****************************************************************
164 Free the static libnetapi context
165 ****************************************************************/
167 NET_API_STATUS libnetapi_free(struct libnetapi_ctx *ctx)
172 return NET_API_STATUS_SUCCESS;
175 frame = talloc_stackframe();
176 libnetapi_samr_free(ctx);
178 libnetapi_shutdown_cm(ctx);
186 netlogon_creds_cli_close_global_db();
188 if (ctx == stat_ctx) {
196 return NET_API_STATUS_SUCCESS;
199 /****************************************************************
200 Override the current log level for libnetapi
201 ****************************************************************/
203 NET_API_STATUS libnetapi_set_debuglevel(struct libnetapi_ctx *ctx,
204 const char *debuglevel)
206 TALLOC_CTX *frame = talloc_stackframe();
207 ctx->debuglevel = talloc_strdup(ctx, debuglevel);
209 if (!lp_set_cmdline("log level", debuglevel)) {
211 return W_ERROR_V(WERR_GEN_FAILURE);
214 return NET_API_STATUS_SUCCESS;
217 /****************************************************************
218 ****************************************************************/
220 NET_API_STATUS libnetapi_get_debuglevel(struct libnetapi_ctx *ctx,
223 *debuglevel = ctx->debuglevel;
224 return NET_API_STATUS_SUCCESS;
227 /****************************************************************
228 ****************************************************************/
231 * @brief Get the username of the libnet context
233 * @param[in] ctx The netapi context
235 * @param[in] username A pointer to hold the username.
237 * @return 0 on success, an werror code otherwise.
239 NET_API_STATUS libnetapi_get_username(struct libnetapi_ctx *ctx,
240 const char **username)
243 return W_ERROR_V(WERR_INVALID_PARAMETER);
246 if (username != NULL) {
247 *username = cli_credentials_get_username(ctx->creds);
250 return NET_API_STATUS_SUCCESS;
254 * @brief Get the password of the libnet context
256 * @param[in] ctx The netapi context
258 * @param[in] password A pointer to hold the password.
260 * @return 0 on success, an werror code otherwise.
262 NET_API_STATUS libnetapi_get_password(struct libnetapi_ctx *ctx,
263 const char **password)
266 return W_ERROR_V(WERR_INVALID_PARAMETER);
269 if (password != NULL) {
270 *password = cli_credentials_get_password(ctx->creds);
273 return NET_API_STATUS_SUCCESS;
276 NET_API_STATUS libnetapi_set_username(struct libnetapi_ctx *ctx,
277 const char *username)
279 if (ctx == NULL || username == NULL) {
280 return W_ERROR_V(WERR_INVALID_PARAMETER);
283 cli_credentials_parse_string(ctx->creds, username, CRED_SPECIFIED);
285 return NET_API_STATUS_SUCCESS;
288 NET_API_STATUS libnetapi_set_password(struct libnetapi_ctx *ctx,
289 const char *password)
293 if (ctx == NULL || password == NULL) {
294 return W_ERROR_V(WERR_INVALID_PARAMETER);
297 ok = cli_credentials_set_password(ctx->creds, password, CRED_SPECIFIED);
299 return W_ERROR_V(WERR_INTERNAL_ERROR);
302 return NET_API_STATUS_SUCCESS;
305 NET_API_STATUS libnetapi_set_workgroup(struct libnetapi_ctx *ctx,
306 const char *workgroup)
310 ok = cli_credentials_set_domain(ctx->creds, workgroup, CRED_SPECIFIED);
312 return W_ERROR_V(WERR_INTERNAL_ERROR);
315 return NET_API_STATUS_SUCCESS;
318 /****************************************************************
319 ****************************************************************/
321 NET_API_STATUS libnetapi_set_use_kerberos(struct libnetapi_ctx *ctx)
323 cli_credentials_set_kerberos_state(ctx->creds,
324 CRED_USE_KERBEROS_REQUIRED);
326 return NET_API_STATUS_SUCCESS;
329 /****************************************************************
330 ****************************************************************/
332 NET_API_STATUS libnetapi_set_use_ccache(struct libnetapi_ctx *ctx)
334 uint32_t gensec_features;
336 gensec_features = cli_credentials_get_gensec_features(ctx->creds);
337 gensec_features |= GENSEC_FEATURE_NTLM_CCACHE;
338 cli_credentials_set_gensec_features(ctx->creds, gensec_features);
340 return NET_API_STATUS_SUCCESS;
343 /****************************************************************
344 Return a libnetapi error as a string, caller must free with NetApiBufferFree
345 ****************************************************************/
347 char *libnetapi_errstr(NET_API_STATUS status)
349 TALLOC_CTX *frame = talloc_stackframe();
351 if (status & 0xc0000000) {
352 ret = talloc_strdup(NULL,
353 get_friendly_nt_error_msg(NT_STATUS(status)));
355 ret = talloc_strdup(NULL,
356 get_friendly_werror_msg(W_ERROR(status)));
362 /****************************************************************
363 ****************************************************************/
365 NET_API_STATUS libnetapi_set_error_string(struct libnetapi_ctx *ctx,
366 const char *format, ...)
370 TALLOC_FREE(ctx->error_string);
372 va_start(args, format);
373 ctx->error_string = talloc_vasprintf(ctx, format, args);
376 if (!ctx->error_string) {
377 return W_ERROR_V(WERR_NOT_ENOUGH_MEMORY);
379 return NET_API_STATUS_SUCCESS;
382 /****************************************************************
383 Return a libnetapi_errstr(), caller must free with NetApiBufferFree
384 ****************************************************************/
386 char *libnetapi_get_error_string(struct libnetapi_ctx *ctx,
387 NET_API_STATUS status_in)
389 NET_API_STATUS status;
390 struct libnetapi_ctx *tmp_ctx = ctx;
393 status = libnetapi_getctx(&tmp_ctx);
399 if (tmp_ctx->error_string) {
400 return talloc_strdup(NULL, tmp_ctx->error_string);
403 return libnetapi_errstr(status_in);
406 /****************************************************************
407 ****************************************************************/
409 NET_API_STATUS NetApiBufferAllocate(uint32_t byte_count,
415 return W_ERROR_V(WERR_INSUFFICIENT_BUFFER);
418 if (byte_count == 0) {
422 buf = talloc_size(NULL, byte_count);
424 return W_ERROR_V(WERR_NOT_ENOUGH_MEMORY);
430 return NET_API_STATUS_SUCCESS;
433 /****************************************************************
434 ****************************************************************/
436 NET_API_STATUS NetApiBufferFree(void *buffer)
439 return W_ERROR_V(WERR_INSUFFICIENT_BUFFER);
444 return NET_API_STATUS_SUCCESS;