LCOV - code coverage report
Current view: top level - lib/smbconf - smbconf.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 140 202 69.3 %
Date: 2024-04-21 15:09:00 Functions: 28 29 96.6 %

          Line data    Source code
       1             : /*
       2             :  *  Unix SMB/CIFS implementation.
       3             :  *  libsmbconf - Samba configuration library
       4             :  *  Copyright (C) Michael Adam 2007-2008
       5             :  *  Copyright (C) Guenther Deschner 2007
       6             :  *
       7             :  *  This program is free software; you can redistribute it and/or modify
       8             :  *  it under the terms of the GNU General Public License as published by
       9             :  *  the Free Software Foundation; either version 3 of the License, or
      10             :  *  (at your option) any later version.
      11             :  *
      12             :  *  This program is distributed in the hope that it will be useful,
      13             :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :  *  GNU General Public License for more details.
      16             :  *
      17             :  *  You should have received a copy of the GNU General Public License
      18             :  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
      19             :  */
      20             : 
      21             : #include "includes.h"
      22             : #include "smbconf_private.h"
      23             : 
      24             : /**********************************************************************
      25             :  *
      26             :  * internal helper functions
      27             :  *
      28             :  **********************************************************************/
      29             : 
      30          29 : static sbcErr smbconf_global_check(struct smbconf_ctx *ctx)
      31             : {
      32          29 :         if (!smbconf_share_exists(ctx, GLOBAL_NAME)) {
      33           5 :                 return smbconf_create_share(ctx, GLOBAL_NAME);
      34             :         }
      35             : 
      36          14 :         return SBC_ERR_OK;
      37             : }
      38             : 
      39             : 
      40             : /**********************************************************************
      41             :  *
      42             :  * The actual libsmbconf API functions that are exported.
      43             :  *
      44             :  **********************************************************************/
      45             : 
      46          12 : const char *sbcErrorString(sbcErr error)
      47             : {
      48          12 :         switch (error) {
      49           0 :                 case SBC_ERR_OK:
      50           0 :                         return "SBC_ERR_OK";
      51           0 :                 case SBC_ERR_NOT_IMPLEMENTED:
      52           0 :                         return "SBC_ERR_NOT_IMPLEMENTED";
      53           1 :                 case SBC_ERR_NOT_SUPPORTED:
      54           1 :                         return "SBC_ERR_NOT_SUPPORTED";
      55           2 :                 case SBC_ERR_UNKNOWN_FAILURE:
      56           2 :                         return "SBC_ERR_UNKNOWN_FAILURE";
      57           0 :                 case SBC_ERR_NOMEM:
      58           0 :                         return "SBC_ERR_NOMEM";
      59           0 :                 case SBC_ERR_INVALID_PARAM:
      60           0 :                         return "SBC_ERR_INVALID_PARAM";
      61           1 :                 case SBC_ERR_BADFILE:
      62           1 :                         return "SBC_ERR_BADFILE";
      63           5 :                 case SBC_ERR_NO_SUCH_SERVICE:
      64           5 :                         return "SBC_ERR_NO_SUCH_SERVICE";
      65           0 :                 case SBC_ERR_IO_FAILURE:
      66           0 :                         return "SBC_ERR_IO_FAILURE";
      67           0 :                 case SBC_ERR_CAN_NOT_COMPLETE:
      68           0 :                         return "SBC_ERR_CAN_NOT_COMPLETE";
      69           0 :                 case SBC_ERR_NO_MORE_ITEMS:
      70           0 :                         return "SBC_ERR_NO_MORE_ITEMS";
      71           3 :                 case SBC_ERR_FILE_EXISTS:
      72           3 :                         return "SBC_ERR_FILE_EXISTS";
      73           0 :                 case SBC_ERR_ACCESS_DENIED:
      74           0 :                         return "SBC_ERR_ACCESS_DENIED";
      75             :         }
      76             : 
      77           0 :         return "unknown sbcErr value";
      78             : }
      79             : 
      80             : 
      81             : /**
      82             :  * Tell whether the backend requires messaging to be set up
      83             :  * for the backend to work correctly.
      84             :  */
      85           1 : bool smbconf_backend_requires_messaging(struct smbconf_ctx *ctx)
      86             : {
      87           1 :         return ctx->ops->requires_messaging(ctx);
      88             : }
      89             : 
      90             : /**
      91             :  * Tell whether the source is writeable.
      92             :  */
      93           4 : bool smbconf_is_writeable(struct smbconf_ctx *ctx)
      94             : {
      95           4 :         return ctx->ops->is_writeable(ctx);
      96             : }
      97             : 
      98             : /**
      99             :  * Close the configuration.
     100             :  */
     101         593 : void smbconf_shutdown(struct smbconf_ctx *ctx)
     102             : {
     103         593 :         talloc_free(ctx);
     104         593 : }
     105             : 
     106             : /**
     107             :  * Detect changes in the configuration.
     108             :  * The given csn struct is filled with the current csn.
     109             :  * smbconf_changed() can also be used for initial retrieval
     110             :  * of the csn.
     111             :  */
     112        1054 : bool smbconf_changed(struct smbconf_ctx *ctx, struct smbconf_csn *csn,
     113             :                      const char *service, const char *param)
     114             : {
     115           0 :         struct smbconf_csn old_csn;
     116             : 
     117        1054 :         if (csn == NULL) {
     118           0 :                 return false;
     119             :         }
     120             : 
     121        1054 :         old_csn = *csn;
     122             : 
     123        1054 :         ctx->ops->get_csn(ctx, csn, service, param);
     124        1054 :         return (csn->csn != old_csn.csn);
     125             : }
     126             : 
     127             : /**
     128             :  * Drop the whole configuration (restarting empty).
     129             :  */
     130          41 : sbcErr smbconf_drop(struct smbconf_ctx *ctx)
     131             : {
     132          41 :         return ctx->ops->drop(ctx);
     133             : }
     134             : 
     135             : /**
     136             :  * Get the whole configuration as lists of strings with counts:
     137             :  *
     138             :  *  num_shares   : number of shares
     139             :  *  share_names  : list of length num_shares of share names
     140             :  *  num_params   : list of length num_shares of parameter counts for each share
     141             :  *  param_names  : list of lists of parameter names for each share
     142             :  *  param_values : list of lists of parameter values for each share
     143             :  */
     144         261 : sbcErr smbconf_get_config(struct smbconf_ctx *ctx,
     145             :                           TALLOC_CTX *mem_ctx,
     146             :                           uint32_t *num_shares,
     147             :                           struct smbconf_service ***services)
     148             : {
     149           1 :         sbcErr err;
     150         261 :         TALLOC_CTX *tmp_ctx = NULL;
     151           1 :         uint32_t tmp_num_shares;
     152           1 :         char **tmp_share_names;
     153           1 :         struct smbconf_service **tmp_services;
     154           1 :         uint32_t count;
     155             : 
     156         261 :         if ((num_shares == NULL) || (services == NULL)) {
     157           0 :                 err = SBC_ERR_INVALID_PARAM;
     158           0 :                 goto done;
     159             :         }
     160             : 
     161         261 :         tmp_ctx = talloc_stackframe();
     162             : 
     163         261 :         err = smbconf_get_share_names(ctx, tmp_ctx, &tmp_num_shares,
     164             :                                       &tmp_share_names);
     165         261 :         if (!SBC_ERROR_IS_OK(err)) {
     166           0 :                 goto done;
     167             :         }
     168             : 
     169         261 :         tmp_services = talloc_array(tmp_ctx, struct smbconf_service *,
     170             :                                     tmp_num_shares);
     171         261 :         if (tmp_services == NULL) {
     172           0 :                 err = SBC_ERR_NOMEM;
     173           0 :                 goto done;
     174             :         }
     175             : 
     176        4146 :         for (count = 0; count < tmp_num_shares; count++) {
     177        3890 :                 err = smbconf_get_share(ctx, tmp_services,
     178        3885 :                                         tmp_share_names[count],
     179        3885 :                                         &tmp_services[count]);
     180        3885 :                 if (!SBC_ERROR_IS_OK(err)) {
     181           0 :                         goto done;
     182             :                 }
     183             :         }
     184             : 
     185         261 :         err = SBC_ERR_OK;
     186             : 
     187         261 :         *num_shares = tmp_num_shares;
     188         261 :         if (tmp_num_shares > 0) {
     189          65 :                 *services = talloc_move(mem_ctx, &tmp_services);
     190             :         } else {
     191         196 :                 *services = NULL;
     192             :         }
     193             : 
     194         261 : done:
     195         261 :         talloc_free(tmp_ctx);
     196         261 :         return err;
     197             : }
     198             : 
     199             : /**
     200             :  * get the list of share names defined in the configuration.
     201             :  */
     202         271 : sbcErr smbconf_get_share_names(struct smbconf_ctx *ctx,
     203             :                                TALLOC_CTX *mem_ctx,
     204             :                                uint32_t *num_shares,
     205             :                                char ***share_names)
     206             : {
     207         271 :         return ctx->ops->get_share_names(ctx, mem_ctx, num_shares,
     208             :                                          share_names);
     209             : }
     210             : 
     211             : /**
     212             :  * check if a share/service of a given name exists
     213             :  */
     214     2915987 : bool smbconf_share_exists(struct smbconf_ctx *ctx,
     215             :                           const char *servicename)
     216             : {
     217     2915987 :         return ctx->ops->share_exists(ctx, servicename);
     218             : }
     219             : 
     220             : /**
     221             :  * Add a service if it does not already exist.
     222             :  */
     223         668 : sbcErr smbconf_create_share(struct smbconf_ctx *ctx,
     224             :                             const char *servicename)
     225             : {
     226         668 :         if ((servicename != NULL) && smbconf_share_exists(ctx, servicename)) {
     227           0 :                 return SBC_ERR_FILE_EXISTS;
     228             :         }
     229             : 
     230         667 :         return ctx->ops->create_share(ctx, servicename);
     231             : }
     232             : 
     233             : /**
     234             :  * create and set the definition for a new share (service).
     235             :  */
     236         439 : sbcErr smbconf_create_set_share(struct smbconf_ctx *ctx,
     237             :                                 struct smbconf_service *service)
     238             : {
     239           7 :         sbcErr err, err2;
     240           7 :         int i;
     241         439 :         uint32_t num_includes = 0;
     242         439 :         char **includes = NULL;
     243         439 :         TALLOC_CTX *tmp_ctx = NULL;
     244             : 
     245         439 :         if ((service->name != NULL) && smbconf_share_exists(ctx, service->name))
     246             :         {
     247           0 :                 return SBC_ERR_FILE_EXISTS;
     248             :         }
     249             : 
     250         437 :         err = smbconf_transaction_start(ctx);
     251         437 :         if (!SBC_ERROR_IS_OK(err)) {
     252           0 :                 return err;
     253             :         }
     254             : 
     255         437 :         tmp_ctx = talloc_stackframe();
     256             : 
     257         437 :         err = smbconf_create_share(ctx, service->name);
     258         437 :         if (!SBC_ERROR_IS_OK(err)) {
     259           0 :                 goto cancel;
     260             :         }
     261             : 
     262        2432 :         for (i = 0; i < service->num_params; i++) {
     263        1995 :                 if (strequal(service->param_names[i], "include")) {
     264           0 :                         includes = talloc_realloc(tmp_ctx, includes, char *,
     265             :                                                   num_includes+1);
     266           0 :                         if (includes == NULL) {
     267           0 :                                 err = SBC_ERR_NOMEM;
     268           0 :                                 goto cancel;
     269             :                         }
     270           0 :                         includes[num_includes] = talloc_strdup(includes,
     271           0 :                                                 service->param_values[i]);
     272           0 :                         if (includes[num_includes] == NULL) {
     273           0 :                                 err = SBC_ERR_NOMEM;
     274           0 :                                 goto cancel;
     275             :                         }
     276           0 :                         num_includes++;
     277             :                 } else {
     278        2004 :                         err = smbconf_set_parameter(ctx,
     279        1995 :                                                     service->name,
     280        1995 :                                                     service->param_names[i],
     281        1995 :                                                     service->param_values[i]);
     282        1995 :                         if (!SBC_ERROR_IS_OK(err)) {
     283           0 :                                 goto cancel;
     284             :                         }
     285             :                 }
     286             :         }
     287             : 
     288         437 :         err = smbconf_set_includes(ctx, service->name, num_includes,
     289             :                                    discard_const_p(const char *, includes));
     290         437 :         if (!SBC_ERROR_IS_OK(err)) {
     291           0 :                 goto cancel;
     292             :         }
     293             : 
     294         437 :         err = smbconf_transaction_commit(ctx);
     295             : 
     296         437 :         goto done;
     297             : 
     298           0 : cancel:
     299           0 :         err2 = smbconf_transaction_cancel(ctx);
     300           0 :         if (!SBC_ERROR_IS_OK(err2)) {
     301           0 :                 DEBUG(5, (__location__ ": Error cancelling transaction: %s\n",
     302             :                           sbcErrorString(err2)));
     303             :         }
     304             : 
     305           0 : done:
     306         437 :         talloc_free(tmp_ctx);
     307         437 :         return err;
     308             : }
     309             : 
     310             : /**
     311             :  * get a definition of a share (service) from configuration.
     312             :  */
     313        4945 : sbcErr smbconf_get_share(struct smbconf_ctx *ctx,
     314             :                          TALLOC_CTX *mem_ctx,
     315             :                          const char *servicename,
     316             :                          struct smbconf_service **service)
     317             : {
     318        4945 :         return ctx->ops->get_share(ctx, mem_ctx, servicename, service);
     319             : }
     320             : 
     321             : /**
     322             :  * delete a service from configuration
     323             :  */
     324          20 : sbcErr smbconf_delete_share(struct smbconf_ctx *ctx, const char *servicename)
     325             : {
     326          20 :         if (!smbconf_share_exists(ctx, servicename)) {
     327           2 :                 return SBC_ERR_NO_SUCH_SERVICE;
     328             :         }
     329             : 
     330          18 :         return ctx->ops->delete_share(ctx, servicename);
     331             : }
     332             : 
     333             : /**
     334             :  * set a configuration parameter to the value provided.
     335             :  */
     336        2919 : sbcErr smbconf_set_parameter(struct smbconf_ctx *ctx,
     337             :                              const char *service,
     338             :                              const char *param,
     339             :                              const char *valstr)
     340             : {
     341        2919 :         return ctx->ops->set_parameter(ctx, service, param, valstr);
     342             : }
     343             : 
     344             : /**
     345             :  * Set a global parameter
     346             :  * (i.e. a parameter in the [global] service).
     347             :  *
     348             :  * This also creates [global] when it does not exist.
     349             :  */
     350          11 : sbcErr smbconf_set_global_parameter(struct smbconf_ctx *ctx,
     351             :                                     const char *param, const char *val)
     352             : {
     353          11 :         sbcErr err;
     354             : 
     355          11 :         err = smbconf_global_check(ctx);
     356          11 :         if (!SBC_ERROR_IS_OK(err)) {
     357           0 :                 return err;
     358             :         }
     359          11 :         err = smbconf_set_parameter(ctx, GLOBAL_NAME, param, val);
     360             : 
     361          11 :         return err;
     362             : }
     363             : 
     364             : /**
     365             :  * get the value of a configuration parameter as a string
     366             :  */
     367           6 : sbcErr smbconf_get_parameter(struct smbconf_ctx *ctx,
     368             :                              TALLOC_CTX *mem_ctx,
     369             :                              const char *service,
     370             :                              const char *param,
     371             :                              char **valstr)
     372             : {
     373           6 :         if (valstr == NULL) {
     374           0 :                 return SBC_ERR_INVALID_PARAM;
     375             :         }
     376             : 
     377           6 :         return ctx->ops->get_parameter(ctx, mem_ctx, service, param, valstr);
     378             : }
     379             : 
     380             : /**
     381             :  * Get the value of a global parameter.
     382             :  *
     383             :  * Create [global] if it does not exist.
     384             :  */
     385           0 : sbcErr smbconf_get_global_parameter(struct smbconf_ctx *ctx,
     386             :                                     TALLOC_CTX *mem_ctx,
     387             :                                     const char *param,
     388             :                                     char **valstr)
     389             : {
     390           0 :         sbcErr err;
     391             : 
     392           0 :         err = smbconf_global_check(ctx);
     393           0 :         if (!SBC_ERROR_IS_OK(err)) {
     394           0 :                 return err;
     395             :         }
     396             : 
     397           0 :         err = smbconf_get_parameter(ctx, mem_ctx, GLOBAL_NAME, param,
     398             :                                     valstr);
     399             : 
     400           0 :         return err;
     401             : }
     402             : 
     403             : /**
     404             :  * delete a parameter from configuration
     405             :  */
     406           7 : sbcErr smbconf_delete_parameter(struct smbconf_ctx *ctx,
     407             :                                 const char *service, const char *param)
     408             : {
     409           7 :         return ctx->ops->delete_parameter(ctx, service, param);
     410             : }
     411             : 
     412             : /**
     413             :  * Delete a global parameter.
     414             :  *
     415             :  * Create [global] if it does not exist.
     416             :  */
     417           2 : sbcErr smbconf_delete_global_parameter(struct smbconf_ctx *ctx,
     418             :                                        const char *param)
     419             : {
     420           2 :         sbcErr err;
     421             : 
     422           2 :         err = smbconf_global_check(ctx);
     423           2 :         if (!SBC_ERROR_IS_OK(err)) {
     424           0 :                 return err;
     425             :         }
     426           2 :         err = smbconf_delete_parameter(ctx, GLOBAL_NAME, param);
     427             : 
     428           2 :         return err;
     429             : }
     430             : 
     431          10 : sbcErr smbconf_get_includes(struct smbconf_ctx *ctx,
     432             :                             TALLOC_CTX *mem_ctx,
     433             :                             const char *service,
     434             :                             uint32_t *num_includes, char ***includes)
     435             : {
     436          10 :         return ctx->ops->get_includes(ctx, mem_ctx, service, num_includes,
     437             :                                       includes);
     438             : }
     439             : 
     440           8 : sbcErr smbconf_get_global_includes(struct smbconf_ctx *ctx,
     441             :                                    TALLOC_CTX *mem_ctx,
     442             :                                    uint32_t *num_includes, char ***includes)
     443             : {
     444           0 :         sbcErr err;
     445             : 
     446           8 :         err = smbconf_global_check(ctx);
     447           8 :         if (!SBC_ERROR_IS_OK(err)) {
     448           0 :                 return err;
     449             :         }
     450           8 :         err = smbconf_get_includes(ctx, mem_ctx, GLOBAL_NAME,
     451             :                                     num_includes, includes);
     452             : 
     453           8 :         return err;
     454             : }
     455             : 
     456         443 : sbcErr smbconf_set_includes(struct smbconf_ctx *ctx,
     457             :                             const char *service,
     458             :                             uint32_t num_includes, const char **includes)
     459             : {
     460         443 :         return ctx->ops->set_includes(ctx, service, num_includes, includes);
     461             : }
     462             : 
     463           4 : sbcErr smbconf_set_global_includes(struct smbconf_ctx *ctx,
     464             :                                    uint32_t num_includes,
     465             :                                    const char **includes)
     466             : {
     467           0 :         sbcErr err;
     468             : 
     469           4 :         err = smbconf_global_check(ctx);
     470           4 :         if (!SBC_ERROR_IS_OK(err)) {
     471           0 :                 return err;
     472             :         }
     473           4 :         err = smbconf_set_includes(ctx, GLOBAL_NAME,
     474             :                                    num_includes, includes);
     475             : 
     476           4 :         return err;
     477             : }
     478             : 
     479             : 
     480          10 : sbcErr smbconf_delete_includes(struct smbconf_ctx *ctx, const char *service)
     481             : {
     482          10 :         return ctx->ops->delete_includes(ctx, service);
     483             : }
     484             : 
     485           4 : sbcErr smbconf_delete_global_includes(struct smbconf_ctx *ctx)
     486             : {
     487           0 :         sbcErr err;
     488             : 
     489           4 :         err = smbconf_global_check(ctx);
     490           4 :         if (!SBC_ERROR_IS_OK(err)) {
     491           0 :                 return err;
     492             :         }
     493           4 :         err = smbconf_delete_includes(ctx, GLOBAL_NAME);
     494             : 
     495           4 :         return err;
     496             : }
     497             : 
     498         717 : sbcErr smbconf_transaction_start(struct smbconf_ctx *ctx)
     499             : {
     500         717 :         return ctx->ops->transaction_start(ctx);
     501             : }
     502             : 
     503         715 : sbcErr smbconf_transaction_commit(struct smbconf_ctx *ctx)
     504             : {
     505         715 :         return ctx->ops->transaction_commit(ctx);
     506             : }
     507             : 
     508           2 : sbcErr smbconf_transaction_cancel(struct smbconf_ctx *ctx)
     509             : {
     510           2 :         return ctx->ops->transaction_cancel(ctx);
     511             : }

Generated by: LCOV version 1.14