LCOV - code coverage report
Current view: top level - sss_client/autofs - sss_autofs.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 233 0.0 %
Date: 2016-06-29 Functions: 0 7 0.0 %

          Line data    Source code
       1             : /*
       2             :     Authors:
       3             :         Jakub Hrozek <jhrozek@redhat.com>
       4             : 
       5             :     Copyright (C) 2012 Red Hat
       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 <errno.h>
      22             : #include <stdlib.h>
      23             : 
      24             : #include "sss_client/autofs/sss_autofs_private.h"
      25             : #include "sss_client/sss_cli.h"
      26             : 
      27             : /* Historically, autofs map names were just file names. Direct key names
      28             :  * may be full directory paths
      29             :  */
      30             : #define MAX_AUTOMNTMAPNAME_LEN  NAME_MAX
      31             : #define MAX_AUTOMNTKEYNAME_LEN  PATH_MAX
      32             : 
      33             : /* How many entries shall _sss_getautomntent_r retreive at once */
      34             : #define GETAUTOMNTENT_MAX_ENTRIES   512
      35             : 
      36             : struct automtent {
      37             :     char *mapname;
      38             :     size_t cursor;
      39             : };
      40             : 
      41             : static struct sss_getautomntent_data {
      42             :     char *mapname;
      43             :     size_t len;
      44             :     size_t ptr;
      45             :     uint8_t *data;
      46             : } sss_getautomntent_data;
      47             : 
      48             : static void
      49           0 : sss_getautomntent_data_clean(void)
      50             : {
      51           0 :     free(sss_getautomntent_data.data);
      52           0 :     free(sss_getautomntent_data.mapname);
      53           0 :     memset(&sss_getautomntent_data, 0, sizeof(struct sss_getautomntent_data));
      54           0 : }
      55             : 
      56             : errno_t
      57           0 : _sss_setautomntent(const char *mapname, void **context)
      58             : {
      59             :     errno_t ret;
      60             :     int errnop;
      61             :     struct automtent *ctx;
      62             :     char *name;
      63             :     size_t name_len;
      64             :     struct sss_cli_req_data rd;
      65           0 :     uint8_t *repbuf = NULL;
      66             :     size_t replen;
      67           0 :     uint32_t num_results = 0;
      68             : 
      69           0 :     if (!mapname) return EINVAL;
      70             : 
      71           0 :     sss_nss_lock();
      72             : 
      73             :     /* Make sure there are no leftovers from previous runs */
      74           0 :     sss_getautomntent_data_clean();
      75             : 
      76           0 :     ret = sss_strnlen(mapname, MAX_AUTOMNTMAPNAME_LEN, &name_len);
      77           0 :     if (ret != 0) {
      78           0 :         ret = EINVAL;
      79           0 :         goto out;
      80             :     }
      81             : 
      82           0 :     name = malloc(sizeof(char)*name_len + 1);
      83           0 :     if (name == NULL) {
      84           0 :         ret = ENOMEM;
      85           0 :         goto out;
      86             :     }
      87           0 :     strncpy(name, mapname, name_len + 1);
      88             : 
      89           0 :     rd.data = name;
      90           0 :     rd.len = name_len + 1;
      91             : 
      92           0 :     ret = sss_autofs_make_request(SSS_AUTOFS_SETAUTOMNTENT, &rd,
      93             :                                   &repbuf, &replen, &errnop);
      94           0 :     if (ret != SSS_STATUS_SUCCESS) {
      95           0 :         free(name);
      96           0 :         ret = errnop;
      97           0 :         goto out;
      98             :     }
      99             : 
     100             :     /* Get number of results from repbuf. */
     101           0 :     SAFEALIGN_COPY_UINT32(&num_results, repbuf, NULL);
     102             : 
     103             :     /* no results if not found */
     104           0 :     if (num_results == 0) {
     105           0 :         free(name);
     106           0 :         free(repbuf);
     107           0 :         ret = ENOENT;
     108           0 :         goto out;
     109             :     }
     110           0 :     free(repbuf);
     111             : 
     112           0 :     ctx = malloc(sizeof(struct automtent));
     113           0 :     if (!ctx) {
     114           0 :         free(name);
     115           0 :         ret = ENOMEM;
     116           0 :         goto out;
     117             :     }
     118             : 
     119           0 :     ctx->mapname = strdup(name);
     120           0 :     if (!ctx->mapname) {
     121           0 :         free(name);
     122           0 :         free(ctx);
     123           0 :         ret = ENOMEM;
     124           0 :         goto out;
     125             :     }
     126           0 :     ctx->cursor = 0;
     127           0 :     free(name);
     128             : 
     129           0 :     *context = ctx;
     130           0 :     ret = 0;
     131             : out:
     132           0 :     sss_nss_unlock();
     133           0 :     return ret;
     134             : }
     135             : 
     136             : static errno_t
     137           0 : sss_getautomntent_data_return(const char *mapname, char **_key, char **_value)
     138             : {
     139             :     size_t dp;
     140           0 :     uint32_t len = 0;
     141           0 :     char *key = NULL;
     142             :     uint32_t keylen;
     143           0 :     char *value = NULL;
     144             :     uint32_t vallen;
     145             :     errno_t ret;
     146             : 
     147           0 :     if (sss_getautomntent_data.mapname == NULL ||
     148           0 :         sss_getautomntent_data.data == NULL ||
     149           0 :         sss_getautomntent_data.ptr >= sss_getautomntent_data.len) {
     150             :         /* We're done with this buffer */
     151           0 :         ret = ENOENT;
     152           0 :         goto done;
     153             :     }
     154             : 
     155           0 :     ret = strcmp(mapname, sss_getautomntent_data.mapname);
     156           0 :     if (ret != EOK) {
     157             :         /* The map we're looking for is not cached. Let responder
     158             :          * do an implicit setautomntent */
     159           0 :         ret = ENOENT;
     160           0 :         goto done;
     161             :     }
     162             : 
     163           0 :     dp = sss_getautomntent_data.ptr;
     164             : 
     165           0 :     SAFEALIGN_COPY_UINT32(&len, sss_getautomntent_data.data+dp, &dp);
     166           0 :     if (len + sss_getautomntent_data.ptr > sss_getautomntent_data.len) {
     167             :         /* len is bigger than the buffer */
     168           0 :         ret = EIO;
     169           0 :         goto done;
     170             :     }
     171             : 
     172           0 :     if (len == 0) {
     173             :         /* There are no more records. */
     174           0 :         *_key = NULL;
     175           0 :         *_value = NULL;
     176           0 :         ret = ENOENT;
     177           0 :         goto done;
     178             :     }
     179             : 
     180           0 :     SAFEALIGN_COPY_UINT32(&keylen, sss_getautomntent_data.data+dp, &dp);
     181           0 :     if (keylen + dp > sss_getautomntent_data.len) {
     182           0 :         ret = EIO;
     183           0 :         goto done;
     184             :     }
     185             : 
     186           0 :     key = malloc(keylen);
     187           0 :     if (!key) {
     188           0 :         ret = ENOMEM;
     189           0 :         goto done;
     190             :     }
     191             : 
     192           0 :     safealign_memcpy(key, sss_getautomntent_data.data+dp, keylen, &dp);
     193             : 
     194           0 :     SAFEALIGN_COPY_UINT32(&vallen, sss_getautomntent_data.data+dp, &dp);
     195           0 :     if (vallen + dp > sss_getautomntent_data.len) {
     196           0 :         ret = EIO;
     197           0 :         goto done;
     198             :     }
     199             : 
     200           0 :     value = malloc(vallen);
     201           0 :     if (!value) {
     202           0 :         ret = ENOMEM;
     203           0 :         goto done;
     204             :     }
     205             : 
     206           0 :     safealign_memcpy(value, sss_getautomntent_data.data+dp, vallen, &dp);
     207             : 
     208           0 :     sss_getautomntent_data.ptr = dp;
     209           0 :     *_key = key;
     210           0 :     *_value = value;
     211           0 :     return EOK;
     212             : 
     213             : done:
     214           0 :     free(key);
     215           0 :     free(value);
     216           0 :     sss_getautomntent_data_clean();
     217           0 :     return ret;
     218             : }
     219             : 
     220             : /* The repbuf is owned by the sss_getautomntent_data once this
     221             :  * function is called */
     222             : static errno_t
     223           0 : sss_getautomntent_data_save(const char *mapname, uint8_t **repbuf, size_t replen)
     224             : {
     225             :     size_t rp;
     226             :     uint32_t num;
     227             : 
     228           0 :     rp = 0;
     229           0 :     SAFEALIGN_COPY_UINT32(&num, *repbuf+rp, &rp);
     230           0 :     if (num == 0) {
     231           0 :         free(*repbuf);
     232           0 :         return ENOENT;
     233             :     }
     234             : 
     235           0 :     sss_getautomntent_data.mapname = strdup(mapname);
     236           0 :     if (sss_getautomntent_data.mapname == NULL) {
     237           0 :         free(*repbuf);
     238           0 :         return ENOENT;
     239             :     }
     240             : 
     241           0 :     sss_getautomntent_data.data = *repbuf;
     242           0 :     sss_getautomntent_data.len = replen;
     243           0 :     sss_getautomntent_data.ptr = rp;
     244           0 :     *repbuf = NULL;
     245           0 :     return EOK;
     246             : }
     247             : 
     248             : errno_t
     249           0 : _sss_getautomntent_r(char **key, char **value, void *context)
     250             : {
     251             :     int errnop;
     252             :     errno_t ret;
     253             :     size_t name_len;
     254             :     struct sss_cli_req_data rd;
     255           0 :     uint8_t *repbuf = NULL;
     256             :     size_t replen;
     257             :     struct automtent *ctx;
     258           0 :     size_t ctr = 0;
     259           0 :     size_t data_len = 0;
     260             :     uint8_t *data;
     261             : 
     262           0 :     sss_nss_lock();
     263             : 
     264           0 :     ctx = (struct automtent *) context;
     265           0 :     if (!ctx) {
     266           0 :         ret = EINVAL;
     267           0 :         goto out;
     268             :     }
     269             : 
     270             :     /* Be paranoid in case someone tries to smuggle in a huge map name */
     271           0 :     ret = sss_strnlen(ctx->mapname, MAX_AUTOMNTMAPNAME_LEN, &name_len);
     272           0 :     if (ret != 0) {
     273           0 :         ret = EINVAL;
     274           0 :         goto out;
     275             :     }
     276             : 
     277           0 :     ret = sss_getautomntent_data_return(ctx->mapname, key, value);
     278           0 :     if (ret == EOK) {
     279             :         /* The results are available from cache. Just advance the
     280             :          * cursor and return. */
     281           0 :         ctx->cursor++;
     282           0 :         ret = 0;
     283           0 :         goto out;
     284             :     }
     285             :     /* Don't try to handle any error codes, just go to the responder again */
     286             : 
     287           0 :     data_len = sizeof(uint32_t) +            /* mapname len */
     288             :                name_len + 1 +                /* mapname\0   */
     289           0 :                sizeof(uint32_t) +            /* index into the map */
     290             :                sizeof(uint32_t);             /* num entries to retreive */
     291             : 
     292           0 :     data = malloc(data_len);
     293           0 :     if (!data) {
     294           0 :         ret = ENOMEM;
     295           0 :         goto out;
     296             :     }
     297             : 
     298           0 :     SAFEALIGN_SET_UINT32(data, name_len, &ctr);
     299             : 
     300           0 :     safealign_memcpy(data+ctr, ctx->mapname, name_len + 1, &ctr);
     301             : 
     302           0 :     SAFEALIGN_SET_UINT32(data+ctr, ctx->cursor, &ctr);
     303             : 
     304           0 :     SAFEALIGN_SET_UINT32(data+ctr, GETAUTOMNTENT_MAX_ENTRIES, &ctr);
     305             : 
     306           0 :     rd.data = data;
     307           0 :     rd.len = data_len;
     308             : 
     309           0 :     ret = sss_autofs_make_request(SSS_AUTOFS_GETAUTOMNTENT, &rd,
     310             :                                   &repbuf, &replen, &errnop);
     311           0 :     free(data);
     312           0 :     if (ret != SSS_STATUS_SUCCESS) {
     313           0 :         ret = errnop;
     314           0 :         goto out;
     315             :     }
     316             : 
     317             :     /* Got reply, let's save it and return from "cache" */
     318           0 :     ret = sss_getautomntent_data_save(ctx->mapname, &repbuf, replen);
     319           0 :     if (ret == ENOENT) {
     320             :         /* No results */
     321           0 :         *key = NULL;
     322           0 :         *value = NULL;
     323           0 :         goto out;
     324           0 :     } else if (ret != EOK) {
     325             :         /* Unexpected error */
     326           0 :         goto out;
     327             :     }
     328             : 
     329           0 :     ret = sss_getautomntent_data_return(ctx->mapname, key, value);
     330           0 :     if (ret != EOK) {
     331           0 :         goto out;
     332             :     }
     333             : 
     334             :     /* Advance the cursor so that we'll fetch the next map
     335             :      * next time getautomntent is called */
     336           0 :     ctx->cursor++;
     337           0 :     ret = 0;
     338             : out:
     339           0 :     sss_nss_unlock();
     340           0 :     return ret;
     341             : }
     342             : 
     343             : errno_t
     344           0 : _sss_getautomntbyname_r(const char *key, char **value, void *context)
     345             : {
     346             :     int errnop;
     347             :     errno_t ret;
     348             :     struct automtent *ctx;
     349             :     size_t key_len;
     350             :     size_t name_len;
     351           0 :     size_t data_len = 0;
     352             :     uint8_t *data;
     353           0 :     size_t ctr = 0;
     354             :     struct sss_cli_req_data rd;
     355           0 :     uint8_t *repbuf = NULL;
     356             :     size_t replen;
     357             : 
     358             :     char *buf;
     359             :     uint32_t len;
     360             :     uint32_t vallen;
     361             :     size_t rp;
     362             : 
     363           0 :     sss_nss_lock();
     364             : 
     365           0 :     ctx = (struct automtent *) context;
     366           0 :     if (!ctx || !key) {
     367           0 :         ret = EINVAL;
     368           0 :         goto out;
     369             :     }
     370             : 
     371             :     /* Be paranoid in case someone tries to smuggle in a huge map name */
     372           0 :     ret = sss_strnlen(ctx->mapname, MAX_AUTOMNTMAPNAME_LEN, &name_len);
     373           0 :     if (ret != 0) {
     374           0 :         ret = EINVAL;
     375           0 :         goto out;
     376             :     }
     377             : 
     378           0 :     ret = sss_strnlen(key, MAX_AUTOMNTKEYNAME_LEN, &key_len);
     379           0 :     if (ret != 0) {
     380           0 :         ret = EINVAL;
     381           0 :         goto out;
     382             :     }
     383             : 
     384             : 
     385           0 :     data_len = sizeof(uint32_t) +            /* mapname len */
     386             :                name_len + 1 +                /* mapname\0   */
     387           0 :                sizeof(uint32_t) +            /* keyname len */
     388             :                key_len + 1;                  /* keyname\0   */
     389             : 
     390           0 :     data = malloc(data_len);
     391           0 :     if (!data) {
     392           0 :         ret = ENOMEM;
     393           0 :         goto out;
     394             :     }
     395             : 
     396           0 :     SAFEALIGN_SET_UINT32(data, name_len, &ctr);
     397             : 
     398           0 :     safealign_memcpy(data+ctr, ctx->mapname, name_len + 1, &ctr);
     399             : 
     400           0 :     SAFEALIGN_SET_UINT32(data+ctr, key_len, &ctr);
     401             : 
     402           0 :     safealign_memcpy(data+ctr, key, key_len + 1, &ctr);
     403             : 
     404           0 :     rd.data = data;
     405           0 :     rd.len = data_len;
     406             : 
     407           0 :     ret = sss_autofs_make_request(SSS_AUTOFS_GETAUTOMNTBYNAME, &rd,
     408             :                                   &repbuf, &replen, &errnop);
     409           0 :     free(data);
     410           0 :     if (ret != SSS_STATUS_SUCCESS) {
     411           0 :         ret = errnop;
     412           0 :         goto out;
     413             :     }
     414             : 
     415             :     /* Got reply, let's parse it */
     416           0 :     rp = 0;
     417           0 :     SAFEALIGN_COPY_UINT32(&len, repbuf+rp, &rp);
     418           0 :     if (len == 0) {
     419             :         /* No data */
     420           0 :         *value = NULL;
     421           0 :         ret = ENOENT;
     422           0 :         goto out;
     423             :     }
     424             : 
     425           0 :     SAFEALIGN_COPY_UINT32(&vallen, repbuf+rp, &rp);
     426           0 :     if (vallen > len-rp) {
     427           0 :         ret = EIO;
     428           0 :         goto out;
     429             :     }
     430             : 
     431           0 :     buf = malloc(vallen);
     432           0 :     if (!buf) {
     433           0 :         ret = ENOMEM;
     434           0 :         goto out;
     435             :     }
     436             : 
     437           0 :     safealign_memcpy(buf, repbuf+rp, vallen, &rp);
     438           0 :     *value = buf;
     439             : 
     440           0 :     ret = 0;
     441             : out:
     442           0 :     free(repbuf);
     443           0 :     sss_nss_unlock();
     444           0 :     return ret;
     445             : }
     446             : 
     447             : errno_t
     448           0 : _sss_endautomntent(void **context)
     449             : {
     450             :     struct automtent *fctx;
     451             :     errno_t ret;
     452             :     int errnop;
     453             : 
     454           0 :     if (!context) return 0;
     455             : 
     456           0 :     sss_nss_lock();
     457             : 
     458           0 :     sss_getautomntent_data_clean();
     459             : 
     460           0 :     fctx = (struct automtent *) *context;
     461             : 
     462           0 :     if (fctx != NULL) {
     463           0 :         free(fctx->mapname);
     464           0 :         free(fctx);
     465             :     }
     466             : 
     467           0 :     ret = sss_autofs_make_request(SSS_AUTOFS_ENDAUTOMNTENT,
     468             :                                   NULL, NULL, NULL, &errnop);
     469           0 :     if (ret != SSS_STATUS_SUCCESS) {
     470           0 :         ret = errnop;
     471           0 :         goto out;
     472             :     }
     473             : 
     474           0 :     ret = 0;
     475             : out:
     476           0 :     sss_nss_unlock();
     477           0 :     return ret;
     478             : }

Generated by: LCOV version 1.10