tevent: handle multiplexed fde's in epoll_event_fd_destructor()
[Samba/gebeck_regimport.git] / source3 / lib / netapi / netapi.c
blobb1586ebee61667c1e86bdcc1634f0a68665ba893
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_global(get_dyn_CONFIGFILE())) {
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 TALLOC_CTX *frame = talloc_stackframe();
111 ctx = talloc_zero(frame, struct libnetapi_ctx);
112 if (!ctx) {
113 TALLOC_FREE(frame);
114 return W_ERROR_V(WERR_NOMEM);
117 BlockSignals(True, SIGPIPE);
119 if (getenv("USER")) {
120 ctx->username = talloc_strdup(ctx, getenv("USER"));
121 } else {
122 ctx->username = talloc_strdup(ctx, "");
124 if (!ctx->username) {
125 TALLOC_FREE(frame);
126 fprintf(stderr, "libnetapi_init: out of memory\n");
127 return W_ERROR_V(WERR_NOMEM);
130 status = libnetapi_init_private_context(ctx);
131 if (status != 0) {
132 TALLOC_FREE(frame);
133 return status;
136 libnetapi_initialized = true;
138 talloc_steal(NULL, ctx);
139 *context = stat_ctx = ctx;
141 TALLOC_FREE(frame);
142 return NET_API_STATUS_SUCCESS;
145 /****************************************************************
146 Return the static libnetapi context
147 ****************************************************************/
149 NET_API_STATUS libnetapi_getctx(struct libnetapi_ctx **ctx)
151 if (stat_ctx) {
152 *ctx = stat_ctx;
153 return NET_API_STATUS_SUCCESS;
156 return libnetapi_init(ctx);
159 /****************************************************************
160 Free the static libnetapi context
161 ****************************************************************/
163 NET_API_STATUS libnetapi_free(struct libnetapi_ctx *ctx)
165 TALLOC_CTX *frame;
167 if (!ctx) {
168 return NET_API_STATUS_SUCCESS;
171 frame = talloc_stackframe();
172 libnetapi_samr_free(ctx);
174 libnetapi_shutdown_cm(ctx);
176 if (ctx->krb5_cc_env) {
177 char *env = getenv(KRB5_ENV_CCNAME);
178 if (env && (strequal(ctx->krb5_cc_env, env))) {
179 unsetenv(KRB5_ENV_CCNAME);
183 gfree_names();
184 gfree_loadparm();
185 gfree_charcnv();
186 gfree_interfaces();
188 secrets_shutdown();
190 if (ctx == stat_ctx) {
191 stat_ctx = NULL;
193 TALLOC_FREE(ctx);
195 gfree_debugsyms();
196 talloc_free(frame);
198 return NET_API_STATUS_SUCCESS;
201 /****************************************************************
202 Override the current log level for libnetapi
203 ****************************************************************/
205 NET_API_STATUS libnetapi_set_debuglevel(struct libnetapi_ctx *ctx,
206 const char *debuglevel)
208 TALLOC_CTX *frame = talloc_stackframe();
209 ctx->debuglevel = talloc_strdup(ctx, debuglevel);
211 if (!lp_set_cmdline("log level", debuglevel)) {
212 TALLOC_FREE(frame);
213 return W_ERROR_V(WERR_GENERAL_FAILURE);
215 TALLOC_FREE(frame);
216 return NET_API_STATUS_SUCCESS;
219 /****************************************************************
220 ****************************************************************/
222 NET_API_STATUS libnetapi_get_debuglevel(struct libnetapi_ctx *ctx,
223 char **debuglevel)
225 *debuglevel = ctx->debuglevel;
226 return NET_API_STATUS_SUCCESS;
229 /****************************************************************
230 ****************************************************************/
232 NET_API_STATUS libnetapi_set_username(struct libnetapi_ctx *ctx,
233 const char *username)
235 TALLOC_FREE(ctx->username);
236 ctx->username = talloc_strdup(ctx, username ? username : "");
238 if (!ctx->username) {
239 return W_ERROR_V(WERR_NOMEM);
241 return NET_API_STATUS_SUCCESS;
244 NET_API_STATUS libnetapi_set_password(struct libnetapi_ctx *ctx,
245 const char *password)
247 TALLOC_FREE(ctx->password);
248 ctx->password = talloc_strdup(ctx, password);
249 if (!ctx->password) {
250 return W_ERROR_V(WERR_NOMEM);
252 return NET_API_STATUS_SUCCESS;
255 NET_API_STATUS libnetapi_set_workgroup(struct libnetapi_ctx *ctx,
256 const char *workgroup)
258 TALLOC_FREE(ctx->workgroup);
259 ctx->workgroup = talloc_strdup(ctx, workgroup);
260 if (!ctx->workgroup) {
261 return W_ERROR_V(WERR_NOMEM);
263 return NET_API_STATUS_SUCCESS;
266 /****************************************************************
267 ****************************************************************/
269 NET_API_STATUS libnetapi_set_use_kerberos(struct libnetapi_ctx *ctx)
271 ctx->use_kerberos = true;
272 return NET_API_STATUS_SUCCESS;
275 /****************************************************************
276 ****************************************************************/
278 NET_API_STATUS libnetapi_set_use_ccache(struct libnetapi_ctx *ctx)
280 ctx->use_ccache = true;
281 return NET_API_STATUS_SUCCESS;
284 /****************************************************************
285 Return a libnetapi error as a string, caller must free with NetApiBufferFree
286 ****************************************************************/
288 char *libnetapi_errstr(NET_API_STATUS status)
290 TALLOC_CTX *frame = talloc_stackframe();
291 char *ret;
292 if (status & 0xc0000000) {
293 ret = talloc_strdup(NULL,
294 get_friendly_nt_error_msg(NT_STATUS(status)));
295 } else {
296 ret = talloc_strdup(NULL,
297 get_friendly_werror_msg(W_ERROR(status)));
299 TALLOC_FREE(frame);
300 return ret;
303 /****************************************************************
304 ****************************************************************/
306 NET_API_STATUS libnetapi_set_error_string(struct libnetapi_ctx *ctx,
307 const char *format, ...)
309 va_list args;
311 TALLOC_FREE(ctx->error_string);
313 va_start(args, format);
314 ctx->error_string = talloc_vasprintf(ctx, format, args);
315 va_end(args);
317 if (!ctx->error_string) {
318 return W_ERROR_V(WERR_NOMEM);
320 return NET_API_STATUS_SUCCESS;
323 /****************************************************************
324 Return a libnetapi_errstr(), caller must free with NetApiBufferFree
325 ****************************************************************/
327 char *libnetapi_get_error_string(struct libnetapi_ctx *ctx,
328 NET_API_STATUS status_in)
330 NET_API_STATUS status;
331 struct libnetapi_ctx *tmp_ctx = ctx;
333 if (!tmp_ctx) {
334 status = libnetapi_getctx(&tmp_ctx);
335 if (status != 0) {
336 return NULL;
340 if (tmp_ctx->error_string) {
341 return talloc_strdup(NULL, tmp_ctx->error_string);
344 return libnetapi_errstr(status_in);
347 /****************************************************************
348 ****************************************************************/
350 NET_API_STATUS NetApiBufferAllocate(uint32_t byte_count,
351 void **buffer)
353 void *buf = NULL;
355 if (!buffer) {
356 return W_ERROR_V(WERR_INSUFFICIENT_BUFFER);
359 if (byte_count == 0) {
360 goto done;
363 buf = talloc_size(NULL, byte_count);
364 if (!buf) {
365 return W_ERROR_V(WERR_NOMEM);
368 done:
369 *buffer = buf;
371 return NET_API_STATUS_SUCCESS;
374 /****************************************************************
375 ****************************************************************/
377 NET_API_STATUS NetApiBufferFree(void *buffer)
379 if (!buffer) {
380 return W_ERROR_V(WERR_INSUFFICIENT_BUFFER);
383 talloc_free(buffer);
385 return NET_API_STATUS_SUCCESS;