source: vendor/current/source3/lib/netapi/netapi.c

Last change on this file was 988, checked in by Silvan Scherrer, 9 years ago

Samba Server: update vendor to version 4.4.3

File size: 9.5 KB
Line 
1/*
2 * Unix SMB/CIFS implementation.
3 * NetApi Support
4 * Copyright (C) Guenther Deschner 2007-2008
5 *
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.
10 *
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.
15 *
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/>.
18 */
19
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"
25
26struct libnetapi_ctx *stat_ctx = NULL;
27static bool libnetapi_initialized = false;
28
29/****************************************************************
30****************************************************************/
31
32static NET_API_STATUS libnetapi_init_private_context(struct libnetapi_ctx *ctx)
33{
34 struct libnetapi_private_ctx *priv;
35
36 if (!ctx) {
37 return W_ERROR_V(WERR_INVALID_PARAM);
38 }
39
40 priv = talloc_zero(ctx, struct libnetapi_private_ctx);
41 if (!priv) {
42 return W_ERROR_V(WERR_NOMEM);
43 }
44
45 ctx->private_data = priv;
46
47 return NET_API_STATUS_SUCCESS;
48}
49
50/****************************************************************
51Create a libnetapi context, for use in non-Samba applications. This
52loads the smb.conf file and sets the debug level to 0, so that
53applications are not flooded with debug logs at level 10, when they
54were not expecting it.
55****************************************************************/
56
57NET_API_STATUS libnetapi_init(struct libnetapi_ctx **context)
58{
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;
64 }
65
66#if 0
67 talloc_enable_leak_report();
68#endif
69 frame = talloc_stackframe();
70
71 /* When libnetapi is invoked from an application, it does not
72 * want to be swamped with level 10 debug messages, even if
73 * this has been set for the server in smb.conf */
74 lp_set_cmdline("log level", "0");
75 setup_logging("libnetapi", DEBUG_STDERR);
76
77 if (!lp_load_global(get_dyn_CONFIGFILE())) {
78 TALLOC_FREE(frame);
79 fprintf(stderr, "error loading %s\n", get_dyn_CONFIGFILE() );
80 return W_ERROR_V(WERR_GENERAL_FAILURE);
81 }
82
83 init_names();
84 load_interfaces();
85 reopen_logs();
86
87 BlockSignals(True, SIGPIPE);
88
89 ret = libnetapi_net_init(context);
90 TALLOC_FREE(frame);
91 return ret;
92}
93
94/****************************************************************
95Create a libnetapi context, for use inside the 'net' binary.
96
97As we know net has already loaded the smb.conf file, and set the debug
98level etc, this avoids doing so again (which causes trouble with -d on
99the command line).
100****************************************************************/
101
102NET_API_STATUS libnetapi_net_init(struct libnetapi_ctx **context)
103{
104 NET_API_STATUS status;
105 struct libnetapi_ctx *ctx = NULL;
106 TALLOC_CTX *frame = talloc_stackframe();
107
108 ctx = talloc_zero(frame, struct libnetapi_ctx);
109 if (!ctx) {
110 TALLOC_FREE(frame);
111 return W_ERROR_V(WERR_NOMEM);
112 }
113
114 BlockSignals(True, SIGPIPE);
115
116 if (getenv("USER")) {
117 ctx->username = talloc_strdup(ctx, getenv("USER"));
118 } else {
119 ctx->username = talloc_strdup(ctx, "");
120 }
121 if (!ctx->username) {
122 TALLOC_FREE(frame);
123 fprintf(stderr, "libnetapi_init: out of memory\n");
124 return W_ERROR_V(WERR_NOMEM);
125 }
126
127 status = libnetapi_init_private_context(ctx);
128 if (status != 0) {
129 TALLOC_FREE(frame);
130 return status;
131 }
132
133 libnetapi_initialized = true;
134
135 talloc_steal(NULL, ctx);
136 *context = stat_ctx = ctx;
137
138 TALLOC_FREE(frame);
139 return NET_API_STATUS_SUCCESS;
140}
141
142/****************************************************************
143 Return the static libnetapi context
144****************************************************************/
145
146NET_API_STATUS libnetapi_getctx(struct libnetapi_ctx **ctx)
147{
148 if (stat_ctx) {
149 *ctx = stat_ctx;
150 return NET_API_STATUS_SUCCESS;
151 }
152
153 return libnetapi_init(ctx);
154}
155
156/****************************************************************
157 Free the static libnetapi context
158****************************************************************/
159
160NET_API_STATUS libnetapi_free(struct libnetapi_ctx *ctx)
161{
162 TALLOC_CTX *frame;
163
164 if (!ctx) {
165 return NET_API_STATUS_SUCCESS;
166 }
167
168 frame = talloc_stackframe();
169 libnetapi_samr_free(ctx);
170
171 libnetapi_shutdown_cm(ctx);
172
173 if (ctx->krb5_cc_env) {
174 char *env = getenv(KRB5_ENV_CCNAME);
175 if (env && (strequal(ctx->krb5_cc_env, env))) {
176 unsetenv(KRB5_ENV_CCNAME);
177 }
178 }
179
180 gfree_names();
181 gfree_loadparm();
182 gfree_charcnv();
183 gfree_interfaces();
184
185 secrets_shutdown();
186
187 if (ctx == stat_ctx) {
188 stat_ctx = NULL;
189 }
190 TALLOC_FREE(ctx);
191
192 gfree_debugsyms();
193 talloc_free(frame);
194
195 return NET_API_STATUS_SUCCESS;
196}
197
198/****************************************************************
199 Override the current log level for libnetapi
200****************************************************************/
201
202NET_API_STATUS libnetapi_set_debuglevel(struct libnetapi_ctx *ctx,
203 const char *debuglevel)
204{
205 TALLOC_CTX *frame = talloc_stackframe();
206 ctx->debuglevel = talloc_strdup(ctx, debuglevel);
207
208 if (!lp_set_cmdline("log level", debuglevel)) {
209 TALLOC_FREE(frame);
210 return W_ERROR_V(WERR_GENERAL_FAILURE);
211 }
212 TALLOC_FREE(frame);
213 return NET_API_STATUS_SUCCESS;
214}
215
216/****************************************************************
217****************************************************************/
218
219NET_API_STATUS libnetapi_get_debuglevel(struct libnetapi_ctx *ctx,
220 char **debuglevel)
221{
222 *debuglevel = ctx->debuglevel;
223 return NET_API_STATUS_SUCCESS;
224}
225
226/****************************************************************
227****************************************************************/
228
229NET_API_STATUS libnetapi_set_username(struct libnetapi_ctx *ctx,
230 const char *username)
231{
232 TALLOC_FREE(ctx->username);
233 ctx->username = talloc_strdup(ctx, username ? username : "");
234
235 if (!ctx->username) {
236 return W_ERROR_V(WERR_NOMEM);
237 }
238 return NET_API_STATUS_SUCCESS;
239}
240
241NET_API_STATUS libnetapi_set_password(struct libnetapi_ctx *ctx,
242 const char *password)
243{
244 TALLOC_FREE(ctx->password);
245 ctx->password = talloc_strdup(ctx, password);
246 if (!ctx->password) {
247 return W_ERROR_V(WERR_NOMEM);
248 }
249 return NET_API_STATUS_SUCCESS;
250}
251
252NET_API_STATUS libnetapi_set_workgroup(struct libnetapi_ctx *ctx,
253 const char *workgroup)
254{
255 TALLOC_FREE(ctx->workgroup);
256 ctx->workgroup = talloc_strdup(ctx, workgroup);
257 if (!ctx->workgroup) {
258 return W_ERROR_V(WERR_NOMEM);
259 }
260 return NET_API_STATUS_SUCCESS;
261}
262
263/****************************************************************
264****************************************************************/
265
266NET_API_STATUS libnetapi_set_use_kerberos(struct libnetapi_ctx *ctx)
267{
268 ctx->use_kerberos = true;
269 return NET_API_STATUS_SUCCESS;
270}
271
272/****************************************************************
273****************************************************************/
274
275NET_API_STATUS libnetapi_set_use_ccache(struct libnetapi_ctx *ctx)
276{
277 ctx->use_ccache = true;
278 return NET_API_STATUS_SUCCESS;
279}
280
281/****************************************************************
282Return a libnetapi error as a string, caller must free with NetApiBufferFree
283****************************************************************/
284
285char *libnetapi_errstr(NET_API_STATUS status)
286{
287 TALLOC_CTX *frame = talloc_stackframe();
288 char *ret;
289 if (status & 0xc0000000) {
290 ret = talloc_strdup(NULL,
291 get_friendly_nt_error_msg(NT_STATUS(status)));
292 } else {
293 ret = talloc_strdup(NULL,
294 get_friendly_werror_msg(W_ERROR(status)));
295 }
296 TALLOC_FREE(frame);
297 return ret;
298}
299
300/****************************************************************
301****************************************************************/
302
303NET_API_STATUS libnetapi_set_error_string(struct libnetapi_ctx *ctx,
304 const char *format, ...)
305{
306 va_list args;
307
308 TALLOC_FREE(ctx->error_string);
309
310 va_start(args, format);
311 ctx->error_string = talloc_vasprintf(ctx, format, args);
312 va_end(args);
313
314 if (!ctx->error_string) {
315 return W_ERROR_V(WERR_NOMEM);
316 }
317 return NET_API_STATUS_SUCCESS;
318}
319
320/****************************************************************
321Return a libnetapi_errstr(), caller must free with NetApiBufferFree
322****************************************************************/
323
324char *libnetapi_get_error_string(struct libnetapi_ctx *ctx,
325 NET_API_STATUS status_in)
326{
327 NET_API_STATUS status;
328 struct libnetapi_ctx *tmp_ctx = ctx;
329
330 if (!tmp_ctx) {
331 status = libnetapi_getctx(&tmp_ctx);
332 if (status != 0) {
333 return NULL;
334 }
335 }
336
337 if (tmp_ctx->error_string) {
338 return talloc_strdup(NULL, tmp_ctx->error_string);
339 }
340
341 return libnetapi_errstr(status_in);
342}
343
344/****************************************************************
345****************************************************************/
346
347NET_API_STATUS NetApiBufferAllocate(uint32_t byte_count,
348 void **buffer)
349{
350 void *buf = NULL;
351
352 if (!buffer) {
353 return W_ERROR_V(WERR_INSUFFICIENT_BUFFER);
354 }
355
356 if (byte_count == 0) {
357 goto done;
358 }
359
360 buf = talloc_size(NULL, byte_count);
361 if (!buf) {
362 return W_ERROR_V(WERR_NOMEM);
363 }
364
365 done:
366 *buffer = buf;
367
368 return NET_API_STATUS_SUCCESS;
369}
370
371/****************************************************************
372****************************************************************/
373
374NET_API_STATUS NetApiBufferFree(void *buffer)
375{
376 if (!buffer) {
377 return W_ERROR_V(WERR_INSUFFICIENT_BUFFER);
378 }
379
380 talloc_free(buffer);
381
382 return NET_API_STATUS_SUCCESS;
383}
Note: See TracBrowser for help on using the repository browser.