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

Generated by: LCOV version 1.14