tevent: add tevent_req_defer_callback()
[Samba/gebeck_regimport.git] / source3 / lib / netapi / netapi.c
blob14259864ae2bce4f7fb979b3c74e4bb5a19f2acc
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 "lib/netapi/netapi.h"
22 #include "lib/netapi/netapi_private.h"
23 #include "secrets.h"
24 #include "krb5_env.h"
26 struct libnetapi_ctx *stat_ctx = NULL;
27 static bool libnetapi_initialized = false;
29 /****************************************************************
30 ****************************************************************/
32 static NET_API_STATUS libnetapi_init_private_context(struct libnetapi_ctx *ctx)
34 struct libnetapi_private_ctx *priv;
36 if (!ctx) {
37 return W_ERROR_V(WERR_INVALID_PARAM);
40 priv = talloc_zero(ctx, struct libnetapi_private_ctx);
41 if (!priv) {
42 return W_ERROR_V(WERR_NOMEM);
45 ctx->private_data = priv;
47 return NET_API_STATUS_SUCCESS;
50 /****************************************************************
51 Create a libnetapi context, for use in non-Samba applications. This
52 loads the smb.conf file and sets the debug level to 0, so that
53 applications are not flooded with debug logs at level 10, when they
54 were not expecting it.
55 ****************************************************************/
57 NET_API_STATUS libnetapi_init(struct libnetapi_ctx **context)
59 NET_API_STATUS ret;
60 TALLOC_CTX *frame;
61 if (stat_ctx && libnetapi_initialized) {
62 *context = stat_ctx;
63 return NET_API_STATUS_SUCCESS;
66 #if 0
67 talloc_enable_leak_report();
68 #endif
69 frame = talloc_stackframe();
71 /* Case tables must be loaded before any string comparisons occour */
72 load_case_tables_library();
74 /* When libnetapi is invoked from an application, it does not
75 * want to be swamped with level 10 debug messages, even if
76 * this has been set for the server in smb.conf */
77 lp_set_cmdline("log level", "0");
78 setup_logging("libnetapi", DEBUG_STDERR);
80 if (!lp_load(get_dyn_CONFIGFILE(), true, false, false, true)) {
81 TALLOC_FREE(frame);
82 fprintf(stderr, "error loading %s\n", get_dyn_CONFIGFILE() );
83 return W_ERROR_V(WERR_GENERAL_FAILURE);
86 init_names();
87 load_interfaces();
88 reopen_logs();
90 BlockSignals(True, SIGPIPE);
92 ret = libnetapi_net_init(context);
93 TALLOC_FREE(frame);
94 return ret;
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
102 the command line).
103 ****************************************************************/
105 NET_API_STATUS libnetapi_net_init(struct libnetapi_ctx **context)
107 NET_API_STATUS status;
108 struct libnetapi_ctx *ctx = NULL;
109 char *krb5_cc_env = NULL;
111 TALLOC_CTX *frame = talloc_stackframe();
113 ctx = talloc_zero(frame, struct libnetapi_ctx);
114 if (!ctx) {
115 TALLOC_FREE(frame);
116 return W_ERROR_V(WERR_NOMEM);
119 BlockSignals(True, SIGPIPE);
121 krb5_cc_env = getenv(KRB5_ENV_CCNAME);
122 if (!krb5_cc_env || (strlen(krb5_cc_env) == 0)) {
123 ctx->krb5_cc_env = talloc_strdup(ctx, "MEMORY:libnetapi");
124 setenv(KRB5_ENV_CCNAME, ctx->krb5_cc_env, 1);
127 if (getenv("USER")) {
128 ctx->username = talloc_strdup(ctx, getenv("USER"));
129 } else {
130 ctx->username = talloc_strdup(ctx, "");
132 if (!ctx->username) {
133 TALLOC_FREE(frame);
134 fprintf(stderr, "libnetapi_init: out of memory\n");
135 return W_ERROR_V(WERR_NOMEM);
138 status = libnetapi_init_private_context(ctx);
139 if (status != 0) {
140 TALLOC_FREE(frame);
141 return status;
144 libnetapi_initialized = true;
146 talloc_steal(NULL, ctx);
147 *context = stat_ctx = ctx;
149 TALLOC_FREE(frame);
150 return NET_API_STATUS_SUCCESS;
153 /****************************************************************
154 Return the static libnetapi context
155 ****************************************************************/
157 NET_API_STATUS libnetapi_getctx(struct libnetapi_ctx **ctx)
159 if (stat_ctx) {
160 *ctx = stat_ctx;
161 return NET_API_STATUS_SUCCESS;
164 return libnetapi_init(ctx);
167 /****************************************************************
168 Free the static libnetapi context
169 ****************************************************************/
171 NET_API_STATUS libnetapi_free(struct libnetapi_ctx *ctx)
173 if (!ctx) {
174 return NET_API_STATUS_SUCCESS;
177 libnetapi_samr_free(ctx);
179 libnetapi_shutdown_cm(ctx);
181 if (ctx->krb5_cc_env) {
182 char *env = getenv(KRB5_ENV_CCNAME);
183 if (env && (strequal(ctx->krb5_cc_env, env))) {
184 unsetenv(KRB5_ENV_CCNAME);
188 gfree_names();
189 gfree_loadparm();
190 gfree_charcnv();
191 gfree_interfaces();
193 secrets_shutdown();
195 if (ctx == stat_ctx) {
196 stat_ctx = NULL;
198 TALLOC_FREE(ctx);
200 gfree_debugsyms();
202 return NET_API_STATUS_SUCCESS;
205 /****************************************************************
206 Override the current log level for libnetapi
207 ****************************************************************/
209 NET_API_STATUS libnetapi_set_debuglevel(struct libnetapi_ctx *ctx,
210 const char *debuglevel)
212 TALLOC_CTX *frame = talloc_stackframe();
213 ctx->debuglevel = talloc_strdup(ctx, debuglevel);
215 if (!lp_set_cmdline("log level", debuglevel)) {
216 TALLOC_FREE(frame);
217 return W_ERROR_V(WERR_GENERAL_FAILURE);
219 TALLOC_FREE(frame);
220 return NET_API_STATUS_SUCCESS;
223 /****************************************************************
224 ****************************************************************/
226 NET_API_STATUS libnetapi_get_debuglevel(struct libnetapi_ctx *ctx,
227 char **debuglevel)
229 *debuglevel = ctx->debuglevel;
230 return NET_API_STATUS_SUCCESS;
233 /****************************************************************
234 ****************************************************************/
236 NET_API_STATUS libnetapi_set_username(struct libnetapi_ctx *ctx,
237 const char *username)
239 TALLOC_FREE(ctx->username);
240 ctx->username = talloc_strdup(ctx, username ? username : "");
242 if (!ctx->username) {
243 return W_ERROR_V(WERR_NOMEM);
245 return NET_API_STATUS_SUCCESS;
248 NET_API_STATUS libnetapi_set_password(struct libnetapi_ctx *ctx,
249 const char *password)
251 TALLOC_FREE(ctx->password);
252 ctx->password = talloc_strdup(ctx, password);
253 if (!ctx->password) {
254 return W_ERROR_V(WERR_NOMEM);
256 return NET_API_STATUS_SUCCESS;
259 NET_API_STATUS libnetapi_set_workgroup(struct libnetapi_ctx *ctx,
260 const char *workgroup)
262 TALLOC_FREE(ctx->workgroup);
263 ctx->workgroup = talloc_strdup(ctx, workgroup);
264 if (!ctx->workgroup) {
265 return W_ERROR_V(WERR_NOMEM);
267 return NET_API_STATUS_SUCCESS;
270 /****************************************************************
271 ****************************************************************/
273 NET_API_STATUS libnetapi_set_use_kerberos(struct libnetapi_ctx *ctx)
275 ctx->use_kerberos = true;
276 return NET_API_STATUS_SUCCESS;
279 NET_API_STATUS libnetapi_set_use_ccache(struct libnetapi_ctx *ctx)
281 ctx->use_ccache = true;
282 return NET_API_STATUS_SUCCESS;
285 /****************************************************************
286 Return a libnetapi error as a string, caller must free with NetApiBufferFree
287 ****************************************************************/
289 char *libnetapi_errstr(NET_API_STATUS status)
291 TALLOC_CTX *frame = talloc_stackframe();
292 char *ret;
293 if (status & 0xc0000000) {
294 ret = talloc_strdup(NULL,
295 get_friendly_nt_error_msg(NT_STATUS(status)));
296 } else {
297 ret = talloc_strdup(NULL,
298 get_friendly_werror_msg(W_ERROR(status)));
300 TALLOC_FREE(frame);
301 return ret;
304 /****************************************************************
305 ****************************************************************/
307 NET_API_STATUS libnetapi_set_error_string(struct libnetapi_ctx *ctx,
308 const char *format, ...)
310 va_list args;
312 TALLOC_FREE(ctx->error_string);
314 va_start(args, format);
315 ctx->error_string = talloc_vasprintf(ctx, format, args);
316 va_end(args);
318 if (!ctx->error_string) {
319 return W_ERROR_V(WERR_NOMEM);
321 return NET_API_STATUS_SUCCESS;
324 /****************************************************************
325 Return a libnetapi_errstr(), caller must free with NetApiBufferFree
326 ****************************************************************/
328 char *libnetapi_get_error_string(struct libnetapi_ctx *ctx,
329 NET_API_STATUS status_in)
331 NET_API_STATUS status;
332 struct libnetapi_ctx *tmp_ctx = ctx;
334 if (!tmp_ctx) {
335 status = libnetapi_getctx(&tmp_ctx);
336 if (status != 0) {
337 return NULL;
341 if (tmp_ctx->error_string) {
342 return talloc_strdup(NULL, tmp_ctx->error_string);
345 return libnetapi_errstr(status_in);
348 /****************************************************************
349 ****************************************************************/
351 NET_API_STATUS NetApiBufferAllocate(uint32_t byte_count,
352 void **buffer)
354 void *buf = NULL;
356 if (!buffer) {
357 return W_ERROR_V(WERR_INSUFFICIENT_BUFFER);
360 if (byte_count == 0) {
361 goto done;
364 buf = talloc_size(NULL, byte_count);
365 if (!buf) {
366 return W_ERROR_V(WERR_NOMEM);
369 done:
370 *buffer = buf;
372 return NET_API_STATUS_SUCCESS;
375 /****************************************************************
376 ****************************************************************/
378 NET_API_STATUS NetApiBufferFree(void *buffer)
380 if (!buffer) {
381 return W_ERROR_V(WERR_INSUFFICIENT_BUFFER);
384 talloc_free(buffer);
386 return NET_API_STATUS_SUCCESS;