s3-talloc Change TALLOC_ZERO_P() to talloc_zero()
[nivanova/samba-autobuild/.git] / source3 / lib / netapi / netapi.c
index 7b3ab321afff1b47c2606de352e7667e06902214..14259864ae2bce4f7fb979b3c74e4bb5a19f2acc 100644 (file)
@@ -24,7 +24,6 @@
 #include "krb5_env.h"
 
 struct libnetapi_ctx *stat_ctx = NULL;
-TALLOC_CTX *frame = NULL;
 static bool libnetapi_initialized = false;
 
 /****************************************************************
@@ -38,7 +37,7 @@ static NET_API_STATUS libnetapi_init_private_context(struct libnetapi_ctx *ctx)
                return W_ERROR_V(WERR_INVALID_PARAM);
        }
 
-       priv = TALLOC_ZERO_P(ctx, struct libnetapi_private_ctx);
+       priv = talloc_zero(ctx, struct libnetapi_private_ctx);
        if (!priv) {
                return W_ERROR_V(WERR_NOMEM);
        }
@@ -49,14 +48,16 @@ static NET_API_STATUS libnetapi_init_private_context(struct libnetapi_ctx *ctx)
 }
 
 /****************************************************************
+Create a libnetapi context, for use in non-Samba applications.  This
+loads the smb.conf file and sets the debug level to 0, so that
+applications are not flooded with debug logs at level 10, when they
+were not expecting it.
 ****************************************************************/
 
 NET_API_STATUS libnetapi_init(struct libnetapi_ctx **context)
 {
-       NET_API_STATUS status;
-       struct libnetapi_ctx *ctx = NULL;
-       char *krb5_cc_env = NULL;
-
+       NET_API_STATUS ret;
+       TALLOC_CTX *frame;
        if (stat_ctx && libnetapi_initialized) {
                *context = stat_ctx;
                return NET_API_STATUS_SUCCESS;
@@ -67,20 +68,16 @@ NET_API_STATUS libnetapi_init(struct libnetapi_ctx **context)
 #endif
        frame = talloc_stackframe();
 
-       ctx = talloc_zero(frame, struct libnetapi_ctx);
-       if (!ctx) {
-               TALLOC_FREE(frame);
-               return W_ERROR_V(WERR_NOMEM);
-       }
+       /* Case tables must be loaded before any string comparisons occour */
+       load_case_tables_library();
 
+       /* When libnetapi is invoked from an application, it does not
+        * want to be swamped with level 10 debug messages, even if
+        * this has been set for the server in smb.conf */
        lp_set_cmdline("log level", "0");
-
-       /* prevent setup_logging() from closing x_stderr... */
        setup_logging("libnetapi", DEBUG_STDERR);
 
-       load_case_tables();
-
-       if (!lp_load(get_dyn_CONFIGFILE(), true, false, false, false)) {
+       if (!lp_load(get_dyn_CONFIGFILE(), true, false, false, true)) {
                TALLOC_FREE(frame);
                fprintf(stderr, "error loading %s\n", get_dyn_CONFIGFILE() );
                return W_ERROR_V(WERR_GENERAL_FAILURE);
@@ -92,16 +89,45 @@ NET_API_STATUS libnetapi_init(struct libnetapi_ctx **context)
 
        BlockSignals(True, SIGPIPE);
 
+       ret = libnetapi_net_init(context);
+       TALLOC_FREE(frame);
+       return ret;
+}
+
+/****************************************************************
+Create a libnetapi context, for use inside the 'net' binary.
+
+As we know net has already loaded the smb.conf file, and set the debug
+level etc, this avoids doing so again (which causes trouble with -d on
+the command line).
+****************************************************************/
+
+NET_API_STATUS libnetapi_net_init(struct libnetapi_ctx **context)
+{
+       NET_API_STATUS status;
+       struct libnetapi_ctx *ctx = NULL;
+       char *krb5_cc_env = NULL;
+
+       TALLOC_CTX *frame = talloc_stackframe();
+
+       ctx = talloc_zero(frame, struct libnetapi_ctx);
+       if (!ctx) {
+               TALLOC_FREE(frame);
+               return W_ERROR_V(WERR_NOMEM);
+       }
+
+       BlockSignals(True, SIGPIPE);
+
        krb5_cc_env = getenv(KRB5_ENV_CCNAME);
        if (!krb5_cc_env || (strlen(krb5_cc_env) == 0)) {
-               ctx->krb5_cc_env = talloc_strdup(frame, "MEMORY:libnetapi");
+               ctx->krb5_cc_env = talloc_strdup(ctx, "MEMORY:libnetapi");
                setenv(KRB5_ENV_CCNAME, ctx->krb5_cc_env, 1);
        }
 
        if (getenv("USER")) {
-               ctx->username = talloc_strdup(frame, getenv("USER"));
+               ctx->username = talloc_strdup(ctx, getenv("USER"));
        } else {
-               ctx->username = talloc_strdup(frame, "");
+               ctx->username = talloc_strdup(ctx, "");
        }
        if (!ctx->username) {
                TALLOC_FREE(frame);
@@ -117,12 +143,15 @@ NET_API_STATUS libnetapi_init(struct libnetapi_ctx **context)
 
        libnetapi_initialized = true;
 
+       talloc_steal(NULL, ctx);
        *context = stat_ctx = ctx;
-
+       
+       TALLOC_FREE(frame);
        return NET_API_STATUS_SUCCESS;
 }
 
 /****************************************************************
+ Return the static libnetapi context
 ****************************************************************/
 
 NET_API_STATUS libnetapi_getctx(struct libnetapi_ctx **ctx)
@@ -136,6 +165,7 @@ NET_API_STATUS libnetapi_getctx(struct libnetapi_ctx **ctx)
 }
 
 /****************************************************************
+ Free the static libnetapi context
 ****************************************************************/
 
 NET_API_STATUS libnetapi_free(struct libnetapi_ctx *ctx)
@@ -157,14 +187,15 @@ NET_API_STATUS libnetapi_free(struct libnetapi_ctx *ctx)
 
        gfree_names();
        gfree_loadparm();
-       gfree_case_tables();
        gfree_charcnv();
        gfree_interfaces();
 
        secrets_shutdown();
 
+       if (ctx == stat_ctx) {
+               stat_ctx = NULL;
+       }
        TALLOC_FREE(ctx);
-       TALLOC_FREE(frame);
 
        gfree_debugsyms();
 
@@ -172,15 +203,20 @@ NET_API_STATUS libnetapi_free(struct libnetapi_ctx *ctx)
 }
 
 /****************************************************************
+ Override the current log level for libnetapi
 ****************************************************************/
 
 NET_API_STATUS libnetapi_set_debuglevel(struct libnetapi_ctx *ctx,
                                        const char *debuglevel)
 {
+       TALLOC_CTX *frame = talloc_stackframe();
        ctx->debuglevel = talloc_strdup(ctx, debuglevel);
+       
        if (!lp_set_cmdline("log level", debuglevel)) {
+               TALLOC_FREE(frame);
                return W_ERROR_V(WERR_GENERAL_FAILURE);
        }
+       TALLOC_FREE(frame);
        return NET_API_STATUS_SUCCESS;
 }
 
@@ -247,15 +283,22 @@ NET_API_STATUS libnetapi_set_use_ccache(struct libnetapi_ctx *ctx)
 }
 
 /****************************************************************
+Return a libnetapi error as a string, caller must free with NetApiBufferFree
 ****************************************************************/
 
-const char *libnetapi_errstr(NET_API_STATUS status)
+char *libnetapi_errstr(NET_API_STATUS status)
 {
+       TALLOC_CTX *frame = talloc_stackframe();
+       char *ret;
        if (status & 0xc0000000) {
-               return get_friendly_nt_error_msg(NT_STATUS(status));
+               ret = talloc_strdup(NULL, 
+                                    get_friendly_nt_error_msg(NT_STATUS(status)));
+       } else {
+               ret = talloc_strdup(NULL,
+                                   get_friendly_werror_msg(W_ERROR(status)));
        }
-
-       return get_friendly_werror_msg(W_ERROR(status));
+       TALLOC_FREE(frame);
+       return ret;
 }
 
 /****************************************************************
@@ -279,9 +322,10 @@ NET_API_STATUS libnetapi_set_error_string(struct libnetapi_ctx *ctx,
 }
 
 /****************************************************************
+Return a libnetapi_errstr(), caller must free with NetApiBufferFree
 ****************************************************************/
 
-const char *libnetapi_get_error_string(struct libnetapi_ctx *ctx,
+char *libnetapi_get_error_string(struct libnetapi_ctx *ctx,
                                       NET_API_STATUS status_in)
 {
        NET_API_STATUS status;
@@ -295,7 +339,7 @@ const char *libnetapi_get_error_string(struct libnetapi_ctx *ctx,
        }
 
        if (tmp_ctx->error_string) {
-               return tmp_ctx->error_string;
+               return talloc_strdup(NULL, tmp_ctx->error_string);
        }
 
        return libnetapi_errstr(status_in);