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"
25 #include "source3/param/loadparm.h"
26 #include "lib/param/param.h"
27 #include "auth/gensec/gensec.h"
29 struct libnetapi_ctx
*stat_ctx
= NULL
;
30 static bool libnetapi_initialized
= false;
32 /****************************************************************
33 ****************************************************************/
35 static NET_API_STATUS
libnetapi_init_private_context(struct libnetapi_ctx
*ctx
)
37 struct libnetapi_private_ctx
*priv
;
40 return W_ERROR_V(WERR_INVALID_PARAMETER
);
43 priv
= talloc_zero(ctx
, struct libnetapi_private_ctx
);
45 return W_ERROR_V(WERR_NOT_ENOUGH_MEMORY
);
48 ctx
->private_data
= priv
;
50 return NET_API_STATUS_SUCCESS
;
53 /****************************************************************
54 Create a libnetapi context, for use in non-Samba applications. This
55 loads the smb.conf file and sets the debug level to 0, so that
56 applications are not flooded with debug logs at level 10, when they
57 were not expecting it.
58 ****************************************************************/
60 NET_API_STATUS
libnetapi_init(struct libnetapi_ctx
**context
)
64 struct loadparm_context
*lp_ctx
= NULL
;
66 if (stat_ctx
&& libnetapi_initialized
) {
68 return NET_API_STATUS_SUCCESS
;
72 talloc_enable_leak_report();
74 frame
= talloc_stackframe();
76 lp_ctx
= loadparm_init_s3(frame
, loadparm_s3_helpers());
79 return W_ERROR_V(WERR_NOT_ENOUGH_MEMORY
);
82 /* When libnetapi is invoked from an application, it does not
83 * want to be swamped with level 10 debug messages, even if
84 * this has been set for the server in smb.conf */
85 lpcfg_set_cmdline(lp_ctx
, "log level", "0");
86 setup_logging("libnetapi", DEBUG_STDERR
);
88 if (!lp_load_global(get_dyn_CONFIGFILE())) {
90 fprintf(stderr
, "error loading %s\n", get_dyn_CONFIGFILE() );
91 return W_ERROR_V(WERR_GEN_FAILURE
);
97 BlockSignals(True
, SIGPIPE
);
99 ret
= libnetapi_net_init(context
, lp_ctx
, NULL
);
100 if (ret
== NET_API_STATUS_SUCCESS
) {
101 talloc_steal(*context
, lp_ctx
);
107 /****************************************************************
108 Create a libnetapi context, for use inside the 'net' binary.
110 As we know net has already loaded the smb.conf file, and set the debug
111 level etc, this avoids doing so again (which causes trouble with -d on
113 ****************************************************************/
115 NET_API_STATUS
libnetapi_net_init(struct libnetapi_ctx
**context
,
116 struct loadparm_context
*lp_ctx
,
117 struct cli_credentials
*creds
)
119 NET_API_STATUS status
;
120 struct libnetapi_ctx
*ctx
= NULL
;
121 TALLOC_CTX
*frame
= NULL
;
123 if (stat_ctx
!= NULL
&& libnetapi_initialized
) {
125 return NET_API_STATUS_SUCCESS
;
128 frame
= talloc_stackframe();
129 ctx
= talloc_zero(frame
, struct libnetapi_ctx
);
132 return W_ERROR_V(WERR_NOT_ENOUGH_MEMORY
);
135 ctx
->lp_ctx
= lp_ctx
;
138 if (ctx
->creds
== NULL
) {
139 ctx
->creds
= cli_credentials_init(ctx
);
140 if (ctx
->creds
== NULL
) {
142 return W_ERROR_V(WERR_NOT_ENOUGH_MEMORY
);
144 /* Ignore return code, as we might not have a smb.conf */
145 (void)cli_credentials_guess(ctx
->creds
, lp_ctx
);
148 BlockSignals(True
, SIGPIPE
);
150 status
= libnetapi_init_private_context(ctx
);
156 libnetapi_initialized
= true;
158 talloc_steal(NULL
, ctx
);
159 *context
= stat_ctx
= ctx
;
162 return NET_API_STATUS_SUCCESS
;
165 /****************************************************************
166 Return the static libnetapi context
167 ****************************************************************/
169 NET_API_STATUS
libnetapi_getctx(struct libnetapi_ctx
**ctx
)
173 return NET_API_STATUS_SUCCESS
;
176 return libnetapi_init(ctx
);
179 /****************************************************************
180 Free the static libnetapi context
181 ****************************************************************/
183 NET_API_STATUS
libnetapi_free(struct libnetapi_ctx
*ctx
)
188 return NET_API_STATUS_SUCCESS
;
191 frame
= talloc_stackframe();
192 libnetapi_samr_free(ctx
);
194 libnetapi_shutdown_cm(ctx
);
202 netlogon_creds_cli_close_global_db();
204 if (ctx
== stat_ctx
) {
212 return NET_API_STATUS_SUCCESS
;
215 /****************************************************************
216 Override the current log level for libnetapi
217 ****************************************************************/
219 NET_API_STATUS
libnetapi_set_debuglevel(struct libnetapi_ctx
*ctx
,
220 const char *debuglevel
)
222 TALLOC_CTX
*frame
= talloc_stackframe();
223 ctx
->debuglevel
= talloc_strdup(ctx
, debuglevel
);
225 if (!lpcfg_set_cmdline(ctx
->lp_ctx
, "log level", debuglevel
)) {
227 return W_ERROR_V(WERR_GEN_FAILURE
);
230 return NET_API_STATUS_SUCCESS
;
233 /****************************************************************
234 ****************************************************************/
236 NET_API_STATUS
libnetapi_set_logfile(struct libnetapi_ctx
*ctx
,
239 TALLOC_CTX
*frame
= talloc_stackframe();
240 ctx
->logfile
= talloc_strdup(ctx
, logfile
);
242 if (!lpcfg_set_cmdline(ctx
->lp_ctx
, "log file", logfile
)) {
244 return W_ERROR_V(WERR_GEN_FAILURE
);
246 debug_set_logfile(logfile
);
247 setup_logging("libnetapi", DEBUG_FILE
);
249 return NET_API_STATUS_SUCCESS
;
252 /****************************************************************
253 ****************************************************************/
255 NET_API_STATUS
libnetapi_get_debuglevel(struct libnetapi_ctx
*ctx
,
258 *debuglevel
= ctx
->debuglevel
;
259 return NET_API_STATUS_SUCCESS
;
262 /****************************************************************
263 ****************************************************************/
266 * @brief Get the username of the libnet context
268 * @param[in] ctx The netapi context
270 * @param[in] username A pointer to hold the username.
272 * @return 0 on success, an werror code otherwise.
274 NET_API_STATUS
libnetapi_get_username(struct libnetapi_ctx
*ctx
,
275 const char **username
)
278 return W_ERROR_V(WERR_INVALID_PARAMETER
);
281 if (username
!= NULL
) {
282 *username
= cli_credentials_get_username(ctx
->creds
);
285 return NET_API_STATUS_SUCCESS
;
289 * @brief Get the password of the libnet context
291 * @param[in] ctx The netapi context
293 * @param[in] password A pointer to hold the password.
295 * @return 0 on success, an werror code otherwise.
297 NET_API_STATUS
libnetapi_get_password(struct libnetapi_ctx
*ctx
,
298 const char **password
)
301 return W_ERROR_V(WERR_INVALID_PARAMETER
);
304 if (password
!= NULL
) {
305 *password
= cli_credentials_get_password(ctx
->creds
);
308 return NET_API_STATUS_SUCCESS
;
311 NET_API_STATUS
libnetapi_set_username(struct libnetapi_ctx
*ctx
,
312 const char *username
)
314 if (ctx
== NULL
|| username
== NULL
) {
315 return W_ERROR_V(WERR_INVALID_PARAMETER
);
318 cli_credentials_parse_string(ctx
->creds
, username
, CRED_SPECIFIED
);
320 return NET_API_STATUS_SUCCESS
;
323 NET_API_STATUS
libnetapi_set_password(struct libnetapi_ctx
*ctx
,
324 const char *password
)
328 if (ctx
== NULL
|| password
== NULL
) {
329 return W_ERROR_V(WERR_INVALID_PARAMETER
);
332 ok
= cli_credentials_set_password(ctx
->creds
, password
, CRED_SPECIFIED
);
334 return W_ERROR_V(WERR_INTERNAL_ERROR
);
337 return NET_API_STATUS_SUCCESS
;
340 NET_API_STATUS
libnetapi_set_workgroup(struct libnetapi_ctx
*ctx
,
341 const char *workgroup
)
345 ok
= cli_credentials_set_domain(ctx
->creds
, workgroup
, CRED_SPECIFIED
);
347 return W_ERROR_V(WERR_INTERNAL_ERROR
);
350 return NET_API_STATUS_SUCCESS
;
354 * @brief Set the cli_credentials to be used in the netapi context
356 * @param[in] ctx The netapi context
358 * @param[in] creds The cli_credentials which should be used by netapi.
360 * @return 0 on success, an werror code otherwise.
362 NET_API_STATUS
libnetapi_set_creds(struct libnetapi_ctx
*ctx
,
363 struct cli_credentials
*creds
)
365 if (ctx
== NULL
|| creds
== NULL
) {
366 return W_ERROR_V(WERR_INVALID_PARAMETER
);
371 return NET_API_STATUS_SUCCESS
;
375 * @brief Get the credentials of the libnet context
377 * @param[in] ctx The netapi context
379 * @param[in] creds A pointer to hold the creds.
381 * @return 0 on success, an werror code otherwise.
383 NET_API_STATUS
libnetapi_get_creds(struct libnetapi_ctx
*ctx
,
384 struct cli_credentials
**creds
)
387 return W_ERROR_V(WERR_INVALID_PARAMETER
);
394 return NET_API_STATUS_SUCCESS
;
397 /****************************************************************
398 ****************************************************************/
400 NET_API_STATUS
libnetapi_set_use_kerberos(struct libnetapi_ctx
*ctx
)
402 cli_credentials_set_kerberos_state(ctx
->creds
,
403 CRED_USE_KERBEROS_REQUIRED
,
406 return NET_API_STATUS_SUCCESS
;
409 /****************************************************************
410 ****************************************************************/
412 NET_API_STATUS
libnetapi_get_use_kerberos(struct libnetapi_ctx
*ctx
,
415 enum credentials_use_kerberos creds_use_kerberos
;
419 creds_use_kerberos
= cli_credentials_get_kerberos_state(ctx
->creds
);
420 if (creds_use_kerberos
> CRED_USE_KERBEROS_DESIRED
) {
424 return NET_API_STATUS_SUCCESS
;
427 /****************************************************************
428 ****************************************************************/
430 NET_API_STATUS
libnetapi_set_use_ccache(struct libnetapi_ctx
*ctx
)
432 cli_credentials_add_gensec_features(ctx
->creds
,
433 GENSEC_FEATURE_NTLM_CCACHE
,
436 return NET_API_STATUS_SUCCESS
;
439 /****************************************************************
440 Return a libnetapi error as a string, caller must free with NetApiBufferFree
441 ****************************************************************/
443 char *libnetapi_errstr(NET_API_STATUS status
)
445 TALLOC_CTX
*frame
= talloc_stackframe();
447 if (status
& 0xc0000000) {
448 ret
= talloc_strdup(NULL
,
449 get_friendly_nt_error_msg(NT_STATUS(status
)));
451 ret
= talloc_strdup(NULL
,
452 get_friendly_werror_msg(W_ERROR(status
)));
458 /****************************************************************
459 ****************************************************************/
461 NET_API_STATUS
libnetapi_set_error_string(struct libnetapi_ctx
*ctx
,
462 const char *format
, ...)
466 TALLOC_FREE(ctx
->error_string
);
468 va_start(args
, format
);
469 ctx
->error_string
= talloc_vasprintf(ctx
, format
, args
);
472 if (!ctx
->error_string
) {
473 return W_ERROR_V(WERR_NOT_ENOUGH_MEMORY
);
475 return NET_API_STATUS_SUCCESS
;
478 /****************************************************************
479 Return a libnetapi_errstr(), caller must free with NetApiBufferFree
480 ****************************************************************/
482 char *libnetapi_get_error_string(struct libnetapi_ctx
*ctx
,
483 NET_API_STATUS status_in
)
485 NET_API_STATUS status
;
486 struct libnetapi_ctx
*tmp_ctx
= ctx
;
489 status
= libnetapi_getctx(&tmp_ctx
);
495 if (tmp_ctx
->error_string
) {
496 return talloc_strdup(NULL
, tmp_ctx
->error_string
);
499 return libnetapi_errstr(status_in
);
502 /****************************************************************
503 ****************************************************************/
505 NET_API_STATUS
NetApiBufferAllocate(uint32_t byte_count
,
511 return W_ERROR_V(WERR_INSUFFICIENT_BUFFER
);
514 if (byte_count
== 0) {
518 buf
= talloc_size(NULL
, byte_count
);
520 return W_ERROR_V(WERR_NOT_ENOUGH_MEMORY
);
526 return NET_API_STATUS_SUCCESS
;
529 /****************************************************************
530 ****************************************************************/
532 NET_API_STATUS
NetApiBufferFree(void *buffer
)
535 return W_ERROR_V(WERR_INSUFFICIENT_BUFFER
);
540 return NET_API_STATUS_SUCCESS
;