LCOV - code coverage report
Current view: top level - source3/lib/netapi - netapi.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 87 186 46.8 %
Date: 2024-06-13 04:01:37 Functions: 12 22 54.5 %

          Line data    Source code
       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 "../libcli/auth/netlogon_creds_cli.h"
      22             : #include "lib/netapi/netapi.h"
      23             : #include "lib/netapi/netapi_private.h"
      24             : #include "secrets.h"
      25             : #include "krb5_env.h"
      26             : #include "source3/param/loadparm.h"
      27             : #include "lib/param/param.h"
      28             : #include "auth/gensec/gensec.h"
      29             : 
      30             : struct libnetapi_ctx *stat_ctx = NULL;
      31             : static bool libnetapi_initialized = false;
      32             : 
      33             : /****************************************************************
      34             : ****************************************************************/
      35             : 
      36         439 : static NET_API_STATUS libnetapi_init_private_context(struct libnetapi_ctx *ctx)
      37             : {
      38             :         struct libnetapi_private_ctx *priv;
      39             : 
      40         439 :         if (!ctx) {
      41           0 :                 return W_ERROR_V(WERR_INVALID_PARAMETER);
      42             :         }
      43             : 
      44         439 :         priv = talloc_zero(ctx, struct libnetapi_private_ctx);
      45         439 :         if (!priv) {
      46           0 :                 return W_ERROR_V(WERR_NOT_ENOUGH_MEMORY);
      47             :         }
      48             : 
      49         439 :         ctx->private_data = priv;
      50             : 
      51         439 :         return NET_API_STATUS_SUCCESS;
      52             : }
      53             : 
      54             : /****************************************************************
      55             : Create a libnetapi context, for use in non-Samba applications.  This
      56             : loads the smb.conf file and sets the debug level to 0, so that
      57             : applications are not flooded with debug logs at level 10, when they
      58             : were not expecting it.
      59             : ****************************************************************/
      60             : 
      61           1 : NET_API_STATUS libnetapi_init(struct libnetapi_ctx **context)
      62             : {
      63             :         NET_API_STATUS ret;
      64             :         TALLOC_CTX *frame;
      65           1 :         if (stat_ctx && libnetapi_initialized) {
      66           1 :                 *context = stat_ctx;
      67           1 :                 return NET_API_STATUS_SUCCESS;
      68             :         }
      69             : 
      70             : #if 0
      71             :         talloc_enable_leak_report();
      72             : #endif
      73           0 :         frame = talloc_stackframe();
      74             : 
      75             :         /* When libnetapi is invoked from an application, it does not
      76             :          * want to be swamped with level 10 debug messages, even if
      77             :          * this has been set for the server in smb.conf */
      78           0 :         lp_set_cmdline("log level", "0");
      79           0 :         setup_logging("libnetapi", DEBUG_STDERR);
      80             : 
      81           0 :         if (!lp_load_global(get_dyn_CONFIGFILE())) {
      82           0 :                 TALLOC_FREE(frame);
      83           0 :                 fprintf(stderr, "error loading %s\n", get_dyn_CONFIGFILE() );
      84           0 :                 return W_ERROR_V(WERR_GEN_FAILURE);
      85             :         }
      86             : 
      87           0 :         load_interfaces();
      88           0 :         reopen_logs();
      89             : 
      90           0 :         BlockSignals(True, SIGPIPE);
      91             : 
      92           0 :         ret = libnetapi_net_init(context);
      93           0 :         TALLOC_FREE(frame);
      94           0 :         return ret;
      95             : }
      96             : 
      97             : /****************************************************************
      98             : Create a libnetapi context, for use inside the 'net' binary.
      99             : 
     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             : ****************************************************************/
     104             : 
     105         439 : NET_API_STATUS libnetapi_net_init(struct libnetapi_ctx **context)
     106             : {
     107             :         NET_API_STATUS status;
     108         439 :         struct libnetapi_ctx *ctx = NULL;
     109         439 :         TALLOC_CTX *frame = talloc_stackframe();
     110         439 :         struct loadparm_context *lp_ctx = NULL;
     111             : 
     112         439 :         ctx = talloc_zero(frame, struct libnetapi_ctx);
     113         439 :         if (!ctx) {
     114           0 :                 TALLOC_FREE(frame);
     115           0 :                 return W_ERROR_V(WERR_NOT_ENOUGH_MEMORY);
     116             :         }
     117             : 
     118         439 :         ctx->creds = cli_credentials_init(ctx);
     119         439 :         if (ctx->creds == NULL) {
     120           0 :                 TALLOC_FREE(frame);
     121           0 :                 return W_ERROR_V(WERR_NOT_ENOUGH_MEMORY);
     122             :         }
     123             : 
     124         439 :         lp_ctx = loadparm_init_s3(frame, loadparm_s3_helpers());
     125         439 :         if (lp_ctx == NULL) {
     126           0 :                 TALLOC_FREE(frame);
     127           0 :                 return W_ERROR_V(WERR_NOT_ENOUGH_MEMORY);
     128             :         }
     129             : 
     130         439 :         BlockSignals(True, SIGPIPE);
     131             : 
     132             :         /* Ignore return code, as we might not have a smb.conf */
     133         439 :         (void)cli_credentials_guess(ctx->creds, lp_ctx);
     134             : 
     135         439 :         status = libnetapi_init_private_context(ctx);
     136         439 :         if (status != 0) {
     137           0 :                 TALLOC_FREE(frame);
     138           0 :                 return status;
     139             :         }
     140             : 
     141         439 :         libnetapi_initialized = true;
     142             : 
     143         439 :         talloc_steal(NULL, ctx);
     144         439 :         *context = stat_ctx = ctx;
     145             :         
     146         439 :         TALLOC_FREE(frame);
     147         439 :         return NET_API_STATUS_SUCCESS;
     148             : }
     149             : 
     150             : /****************************************************************
     151             :  Return the static libnetapi context
     152             : ****************************************************************/
     153             : 
     154         162 : NET_API_STATUS libnetapi_getctx(struct libnetapi_ctx **ctx)
     155             : {
     156         162 :         if (stat_ctx) {
     157         162 :                 *ctx = stat_ctx;
     158         162 :                 return NET_API_STATUS_SUCCESS;
     159             :         }
     160             : 
     161           0 :         return libnetapi_init(ctx);
     162             : }
     163             : 
     164             : /****************************************************************
     165             :  Free the static libnetapi context
     166             : ****************************************************************/
     167             : 
     168         884 : NET_API_STATUS libnetapi_free(struct libnetapi_ctx *ctx)
     169             : {
     170             :         TALLOC_CTX *frame;
     171             : 
     172         884 :         if (!ctx) {
     173         659 :                 return NET_API_STATUS_SUCCESS;
     174             :         }
     175             : 
     176         225 :         frame = talloc_stackframe();
     177         225 :         libnetapi_samr_free(ctx);
     178             : 
     179         225 :         libnetapi_shutdown_cm(ctx);
     180             : 
     181         225 :         gfree_loadparm();
     182         225 :         gfree_charcnv();
     183         225 :         gfree_interfaces();
     184             : 
     185         225 :         secrets_shutdown();
     186             : 
     187         225 :         netlogon_creds_cli_close_global_db();
     188             : 
     189         225 :         if (ctx == stat_ctx) {
     190         225 :                 stat_ctx = NULL;
     191             :         }
     192         225 :         TALLOC_FREE(ctx);
     193             : 
     194         225 :         gfree_debugsyms();
     195         225 :         talloc_free(frame);
     196             : 
     197         225 :         return NET_API_STATUS_SUCCESS;
     198             : }
     199             : 
     200             : /****************************************************************
     201             :  Override the current log level for libnetapi
     202             : ****************************************************************/
     203             : 
     204           0 : NET_API_STATUS libnetapi_set_debuglevel(struct libnetapi_ctx *ctx,
     205             :                                         const char *debuglevel)
     206             : {
     207           0 :         TALLOC_CTX *frame = talloc_stackframe();
     208           0 :         ctx->debuglevel = talloc_strdup(ctx, debuglevel);
     209             :         
     210           0 :         if (!lp_set_cmdline("log level", debuglevel)) {
     211           0 :                 TALLOC_FREE(frame);
     212           0 :                 return W_ERROR_V(WERR_GEN_FAILURE);
     213             :         }
     214           0 :         TALLOC_FREE(frame);
     215           0 :         return NET_API_STATUS_SUCCESS;
     216             : }
     217             : 
     218             : /****************************************************************
     219             : ****************************************************************/
     220             : 
     221           0 : NET_API_STATUS libnetapi_set_logfile(struct libnetapi_ctx *ctx,
     222             :                                      const char *logfile)
     223             : {
     224           0 :         TALLOC_CTX *frame = talloc_stackframe();
     225           0 :         ctx->logfile = talloc_strdup(ctx, logfile);
     226             : 
     227           0 :         if (!lp_set_cmdline("log file", logfile)) {
     228           0 :                 TALLOC_FREE(frame);
     229           0 :                 return W_ERROR_V(WERR_GEN_FAILURE);
     230             :         }
     231           0 :         debug_set_logfile(logfile);
     232           0 :         setup_logging("libnetapi", DEBUG_FILE);
     233           0 :         TALLOC_FREE(frame);
     234           0 :         return NET_API_STATUS_SUCCESS;
     235             : }
     236             : 
     237             : /****************************************************************
     238             : ****************************************************************/
     239             : 
     240           0 : NET_API_STATUS libnetapi_get_debuglevel(struct libnetapi_ctx *ctx,
     241             :                                         char **debuglevel)
     242             : {
     243           0 :         *debuglevel = ctx->debuglevel;
     244           0 :         return NET_API_STATUS_SUCCESS;
     245             : }
     246             : 
     247             : /****************************************************************
     248             : ****************************************************************/
     249             : 
     250             : /**
     251             :  * @brief Get the username of the libnet context
     252             :  *
     253             :  * @param[in]  ctx      The netapi context
     254             :  *
     255             :  * @param[in]  username A pointer to hold the username.
     256             :  *
     257             :  * @return 0 on success, an werror code otherwise.
     258             :  */
     259          77 : NET_API_STATUS libnetapi_get_username(struct libnetapi_ctx *ctx,
     260             :                                       const char **username)
     261             : {
     262          77 :         if (ctx == NULL) {
     263           0 :                 return W_ERROR_V(WERR_INVALID_PARAMETER);
     264             :         }
     265             : 
     266          77 :         if (username != NULL) {
     267          77 :                 *username = cli_credentials_get_username(ctx->creds);
     268             :         }
     269             : 
     270          77 :         return NET_API_STATUS_SUCCESS;
     271             : }
     272             : 
     273             : /**
     274             :  * @brief Get the password of the libnet context
     275             :  *
     276             :  * @param[in]  ctx      The netapi context
     277             :  *
     278             :  * @param[in]  password A pointer to hold the password.
     279             :  *
     280             :  * @return 0 on success, an werror code otherwise.
     281             :  */
     282          77 : NET_API_STATUS libnetapi_get_password(struct libnetapi_ctx *ctx,
     283             :                                       const char **password)
     284             : {
     285          77 :         if (ctx == NULL) {
     286           0 :                 return W_ERROR_V(WERR_INVALID_PARAMETER);
     287             :         }
     288             : 
     289          77 :         if (password != NULL) {
     290          77 :                 *password = cli_credentials_get_password(ctx->creds);
     291             :         }
     292             : 
     293          77 :         return NET_API_STATUS_SUCCESS;
     294             : }
     295             : 
     296           4 : NET_API_STATUS libnetapi_set_username(struct libnetapi_ctx *ctx,
     297             :                                       const char *username)
     298             : {
     299           4 :         if (ctx == NULL || username == NULL) {
     300           0 :                 return W_ERROR_V(WERR_INVALID_PARAMETER);
     301             :         }
     302             : 
     303           4 :         cli_credentials_parse_string(ctx->creds, username, CRED_SPECIFIED);
     304             : 
     305           4 :         return NET_API_STATUS_SUCCESS;
     306             : }
     307             : 
     308           4 : NET_API_STATUS libnetapi_set_password(struct libnetapi_ctx *ctx,
     309             :                                       const char *password)
     310             : {
     311             :         bool ok;
     312             : 
     313           4 :         if (ctx == NULL || password == NULL) {
     314           0 :                 return W_ERROR_V(WERR_INVALID_PARAMETER);
     315             :         }
     316             : 
     317           4 :         ok = cli_credentials_set_password(ctx->creds, password, CRED_SPECIFIED);
     318           4 :         if (!ok) {
     319           0 :                 return W_ERROR_V(WERR_INTERNAL_ERROR);
     320             :         }
     321             : 
     322           4 :         return NET_API_STATUS_SUCCESS;
     323             : }
     324             : 
     325           0 : NET_API_STATUS libnetapi_set_workgroup(struct libnetapi_ctx *ctx,
     326             :                                        const char *workgroup)
     327             : {
     328             :         bool ok;
     329             : 
     330           0 :         ok = cli_credentials_set_domain(ctx->creds, workgroup, CRED_SPECIFIED);
     331           0 :         if (!ok) {
     332           0 :                 return W_ERROR_V(WERR_INTERNAL_ERROR);
     333             :         }
     334             : 
     335           0 :         return NET_API_STATUS_SUCCESS;
     336             : }
     337             : 
     338             : /**
     339             :  * @brief Set the cli_credentials to be used in the netapi context
     340             :  *
     341             :  * @param[in]  ctx    The netapi context
     342             :  *
     343             :  * @param[in]  creds  The cli_credentials which should be used by netapi.
     344             :  *
     345             :  * @return 0 on success, an werror code otherwise.
     346             :  */
     347         435 : NET_API_STATUS libnetapi_set_creds(struct libnetapi_ctx *ctx,
     348             :                                    struct cli_credentials *creds)
     349             : {
     350         435 :         if (ctx == NULL || creds == NULL) {
     351           0 :                 return W_ERROR_V(WERR_INVALID_PARAMETER);
     352             :         }
     353             : 
     354         435 :         ctx->creds = creds;
     355             : 
     356         435 :         return NET_API_STATUS_SUCCESS;
     357             : }
     358             : 
     359             : /****************************************************************
     360             : ****************************************************************/
     361             : 
     362           0 : NET_API_STATUS libnetapi_set_use_kerberos(struct libnetapi_ctx *ctx)
     363             : {
     364           0 :         cli_credentials_set_kerberos_state(ctx->creds,
     365             :                                            CRED_USE_KERBEROS_REQUIRED,
     366             :                                            CRED_SPECIFIED);
     367             : 
     368           0 :         return NET_API_STATUS_SUCCESS;
     369             : }
     370             : 
     371             : /****************************************************************
     372             : ****************************************************************/
     373             : 
     374           0 : NET_API_STATUS libnetapi_get_use_kerberos(struct libnetapi_ctx *ctx,
     375             :                                           int *use_kerberos)
     376             : {
     377             :         enum credentials_use_kerberos creds_use_kerberos;
     378             : 
     379           0 :         *use_kerberos = 0;
     380             : 
     381           0 :         creds_use_kerberos = cli_credentials_get_kerberos_state(ctx->creds);
     382           0 :         if (creds_use_kerberos > CRED_USE_KERBEROS_DESIRED) {
     383           0 :                 *use_kerberos = 1;
     384             :         }
     385             : 
     386           0 :         return NET_API_STATUS_SUCCESS;
     387             : }
     388             : 
     389             : /****************************************************************
     390             : ****************************************************************/
     391             : 
     392           0 : NET_API_STATUS libnetapi_set_use_ccache(struct libnetapi_ctx *ctx)
     393             : {
     394             :         uint32_t gensec_features;
     395             : 
     396           0 :         gensec_features = cli_credentials_get_gensec_features(ctx->creds);
     397           0 :         gensec_features |= GENSEC_FEATURE_NTLM_CCACHE;
     398           0 :         cli_credentials_set_gensec_features(ctx->creds,
     399             :                                             gensec_features,
     400             :                                             CRED_SPECIFIED);
     401             : 
     402           0 :         return NET_API_STATUS_SUCCESS;
     403             : }
     404             : 
     405             : /****************************************************************
     406             : Return a libnetapi error as a string, caller must free with NetApiBufferFree
     407             : ****************************************************************/
     408             : 
     409           0 : char *libnetapi_errstr(NET_API_STATUS status)
     410             : {
     411           0 :         TALLOC_CTX *frame = talloc_stackframe();
     412             :         char *ret;
     413           0 :         if (status & 0xc0000000) {
     414           0 :                 ret = talloc_strdup(NULL, 
     415           0 :                                      get_friendly_nt_error_msg(NT_STATUS(status)));
     416             :         } else {
     417           0 :                 ret = talloc_strdup(NULL,
     418           0 :                                     get_friendly_werror_msg(W_ERROR(status)));
     419             :         }
     420           0 :         TALLOC_FREE(frame);
     421           0 :         return ret;
     422             : }
     423             : 
     424             : /****************************************************************
     425             : ****************************************************************/
     426             : 
     427           0 : NET_API_STATUS libnetapi_set_error_string(struct libnetapi_ctx *ctx,
     428             :                                           const char *format, ...)
     429             : {
     430             :         va_list args;
     431             : 
     432           0 :         TALLOC_FREE(ctx->error_string);
     433             : 
     434           0 :         va_start(args, format);
     435           0 :         ctx->error_string = talloc_vasprintf(ctx, format, args);
     436           0 :         va_end(args);
     437             : 
     438           0 :         if (!ctx->error_string) {
     439           0 :                 return W_ERROR_V(WERR_NOT_ENOUGH_MEMORY);
     440             :         }
     441           0 :         return NET_API_STATUS_SUCCESS;
     442             : }
     443             : 
     444             : /****************************************************************
     445             : Return a libnetapi_errstr(), caller must free with NetApiBufferFree
     446             : ****************************************************************/
     447             : 
     448           0 : char *libnetapi_get_error_string(struct libnetapi_ctx *ctx,
     449             :                                        NET_API_STATUS status_in)
     450             : {
     451             :         NET_API_STATUS status;
     452           0 :         struct libnetapi_ctx *tmp_ctx = ctx;
     453             : 
     454           0 :         if (!tmp_ctx) {
     455           0 :                 status = libnetapi_getctx(&tmp_ctx);
     456           0 :                 if (status != 0) {
     457           0 :                         return NULL;
     458             :                 }
     459             :         }
     460             : 
     461           0 :         if (tmp_ctx->error_string) {
     462           0 :                 return talloc_strdup(NULL, tmp_ctx->error_string);
     463             :         }
     464             : 
     465           0 :         return libnetapi_errstr(status_in);
     466             : }
     467             : 
     468             : /****************************************************************
     469             : ****************************************************************/
     470             : 
     471           1 : NET_API_STATUS NetApiBufferAllocate(uint32_t byte_count,
     472             :                                     void **buffer)
     473             : {
     474           1 :         void *buf = NULL;
     475             : 
     476           1 :         if (!buffer) {
     477           0 :                 return W_ERROR_V(WERR_INSUFFICIENT_BUFFER);
     478             :         }
     479             : 
     480           1 :         if (byte_count == 0) {
     481           0 :                 goto done;
     482             :         }
     483             : 
     484           1 :         buf = talloc_size(NULL, byte_count);
     485           1 :         if (!buf) {
     486           0 :                 return W_ERROR_V(WERR_NOT_ENOUGH_MEMORY);
     487             :         }
     488             : 
     489           1 :  done:
     490           1 :         *buffer = buf;
     491             : 
     492           1 :         return NET_API_STATUS_SUCCESS;
     493             : }
     494             : 
     495             : /****************************************************************
     496             : ****************************************************************/
     497             : 
     498          33 : NET_API_STATUS NetApiBufferFree(void *buffer)
     499             : {
     500          33 :         if (!buffer) {
     501           3 :                 return W_ERROR_V(WERR_INSUFFICIENT_BUFFER);
     502             :         }
     503             : 
     504          30 :         talloc_free(buffer);
     505             : 
     506          30 :         return NET_API_STATUS_SUCCESS;
     507             : }

Generated by: LCOV version 1.13