LCOV - code coverage report
Current view: top level - source3/lib/netapi - netapi.c (source / functions) Hit Total Coverage
Test: coverage report for master 98b443d9 Lines: 94 213 44.1 %
Date: 2024-05-31 13:13:24 Functions: 12 23 52.2 %

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

Generated by: LCOV version 1.14