(root)/
Linux-PAM-1.5.3/
tests/
tst-pam_set_data.c
       1  /*
       2   * Redistribution and use in source and binary forms, with or without
       3   * modification, are permitted provided that the following conditions
       4   * are met:
       5   * 1. Redistributions of source code must retain the above copyright
       6   *    notice, and the entire permission notice in its entirety,
       7   *    including the disclaimer of warranties.
       8   * 2. Redistributions in binary form must reproduce the above copyright
       9   *    notice, this list of conditions and the following disclaimer in the
      10   *    documentation and/or other materials provided with the distribution.
      11   * 3. The name of the author may not be used to endorse or promote
      12   *    products derived from this software without specific prior
      13   *    written permission.
      14   *
      15   * ALTERNATIVELY, this product may be distributed under the terms of
      16   * the GNU Public License, in which case the provisions of the GPL are
      17   * required INSTEAD OF the above restrictions.  (This clause is
      18   * necessary due to a potential bad interaction between the GPL and
      19   * the restrictions contained in a BSD-style copyright.)
      20   *
      21   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
      22   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
      23   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
      24   * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
      25   * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
      26   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      27   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      28   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
      29   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
      30   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
      31   * OF THE POSSIBILITY OF SUCH DAMAGE.
      32   */
      33  
      34  #ifdef HAVE_CONFIG_H
      35  #include <config.h>
      36  #endif
      37  
      38  #include <stdio.h>
      39  #include <unistd.h>
      40  #include <string.h>
      41  
      42  #include <security/pam_appl.h>
      43  #include <security/pam_modules.h>
      44  #include <pam_private.h>
      45  
      46  static int cleanup_was_called = 0;
      47  static int cleanup3_was_called = 0;
      48  static int cleanup3_retval = 0;
      49  static int cleanup6_was_called = 0;
      50  static int cleanup6_retval = 0;
      51  static int cleanup7_was_called = 0;
      52  static int cleanup7_retval = 0;
      53  static int cleanup7b_was_called = 0;
      54  static int cleanup7b_retval = 0;
      55  static int cleanup8_was_called = 0;
      56  static int cleanup8_retval = 0;
      57  
      58  static void
      59  tst_cleanup (pam_handle_t *pamh UNUSED, void *data, int error_status)
      60  {
      61    cleanup_was_called = 1;
      62    fprintf (stderr, "tst_cleanup was called: data=\"%s\", error_status=%d\n",
      63  	   (char *)data, error_status);
      64  }
      65  
      66  static void
      67  tst_cleanup_3 (pam_handle_t *pamh UNUSED, void *data, int error_status)
      68  {
      69    cleanup3_was_called = 1;
      70  
      71    if (strcmp (data, "test3") != 0)
      72      {
      73        fprintf (stderr, "tst_cleanup_3 called with wrong data, got \"%s\"\n",
      74  	       (char *)data);
      75        cleanup3_retval = 1;
      76        return;
      77      }
      78  
      79    free (data);
      80  
      81    if (error_status & PAM_DATA_REPLACE)
      82      {
      83        fprintf (stderr, "tst_cleanup_3 called with PAM_DATA_REPLACE set\n");
      84        cleanup3_retval = 1;
      85        return;
      86      }
      87  
      88    if (error_status & PAM_DATA_SILENT)
      89      {
      90        fprintf (stderr, "tst_cleanup_3 called with PAM_DATA_SILENT set\n");
      91        cleanup3_retval = 1;
      92        return;
      93      }
      94  
      95    if (error_status != 0)
      96      {
      97        fprintf (stderr, "tst_cleanup_3 called with error_status set: %d\n",
      98  	       error_status);
      99        cleanup3_retval = 1;
     100        return;
     101      }
     102  }
     103  
     104  static void
     105  tst_cleanup_6 (pam_handle_t *pamh UNUSED, void *data, int error_status)
     106  {
     107    cleanup6_was_called = 1;
     108  
     109    if (error_status & PAM_DATA_SILENT)
     110      {
     111        fprintf (stderr, "tst_cleanup_6 called with PAM_DATA_SILENT set\n");
     112        cleanup6_retval = 1;
     113        return;
     114      }
     115  
     116    if (error_status & PAM_DATA_REPLACE)
     117      {
     118        if (strcmp (data, "test6a") != 0)
     119  	{
     120  	  fprintf (stderr, "tst_cleanup_6 called with wrong data, got \"%s\"\n",
     121  		   (char *)data);
     122  	  cleanup6_retval = 1;
     123  	  return;
     124  	}
     125  
     126        if (error_status != PAM_DATA_REPLACE)
     127  	{
     128  	  fprintf (stderr, "tst_cleanup_6 called with error_status set: %d\n",
     129  		   error_status);
     130  	  cleanup6_retval = 1;
     131  	  return;
     132  	}
     133      }
     134    else
     135      {
     136        if (strcmp (data, "test6b") != 0)
     137  	{
     138  	  fprintf (stderr, "tst_cleanup_6 called with wrong data, got \"%s\"\n",
     139  		   (char *)data);
     140  	  cleanup6_retval = 1;
     141  	  return;
     142  	}
     143  
     144        if (error_status != 0)
     145  	{
     146  	  fprintf (stderr, "tst_cleanup_6 called with error_status set: %d\n",
     147  		   error_status);
     148  	  cleanup6_retval = 1;
     149  	  return;
     150  	}
     151      }
     152  
     153    free (data);
     154  }
     155  
     156  static void
     157  tst_cleanup_7 (pam_handle_t *pamh UNUSED, void *data, int error_status)
     158  {
     159    cleanup7_was_called = 1;
     160  
     161    if (error_status & PAM_DATA_SILENT)
     162      {
     163        fprintf (stderr, "tst_cleanup_7 called with PAM_DATA_SILENT set\n");
     164        cleanup7_retval = 1;
     165        return;
     166      }
     167  
     168    if (error_status & PAM_DATA_REPLACE)
     169      {
     170        if (strcmp (data, "test7a") != 0)
     171  	{
     172  	  fprintf (stderr, "tst_cleanup_7 called with wrong data, got \"%s\"\n",
     173  		   (char *)data);
     174  	  cleanup7_retval = 1;
     175  	  return;
     176  	}
     177  
     178        if (error_status != PAM_DATA_REPLACE)
     179  	{
     180  	  fprintf (stderr, "tst_cleanup_7 called with error_status set: %d\n",
     181  		   error_status);
     182  	  cleanup7_retval = 1;
     183  	  return;
     184  	}
     185      }
     186    else
     187      {
     188        fprintf (stderr, "tst_cleanup_7 called without PAM_DATA_REPLACE set: %d\n",
     189  	       error_status);
     190        cleanup7_retval = 1;
     191        return;
     192      }
     193  
     194    free (data);
     195  }
     196  
     197  static void
     198  tst_cleanup_7b (pam_handle_t *pamh UNUSED, void *data, int error_status)
     199  {
     200    cleanup7b_was_called = 1;
     201  
     202    if (strcmp (data, "test7b") != 0)
     203      {
     204        fprintf (stderr, "tst_cleanup_7b called with wrong data, got \"%s\"\n",
     205  	       (char *)data);
     206        cleanup7b_retval = 1;
     207        return;
     208      }
     209  
     210    free (data);
     211  
     212    if (error_status & PAM_DATA_REPLACE)
     213      {
     214        fprintf (stderr, "tst_cleanup_7b called with PAM_DATA_REPLACE set\n");
     215        cleanup7b_retval = 1;
     216        return;
     217      }
     218  
     219    if (error_status & PAM_DATA_SILENT)
     220      {
     221        fprintf (stderr, "tst_cleanup_7b called with PAM_DATA_SILENT set\n");
     222        cleanup7b_retval = 1;
     223        return;
     224      }
     225  
     226    if (error_status != 0)
     227      {
     228        fprintf (stderr, "tst_cleanup_7b called with error_status set: %d\n",
     229  	       error_status);
     230        cleanup7b_retval = 1;
     231        return;
     232      }
     233  }
     234  
     235  static void
     236  tst_cleanup_8 (pam_handle_t *pamh UNUSED, void *data, int error_status)
     237  {
     238    cleanup8_was_called = 1;
     239  
     240    if (strcmp (data, "test8") != 0)
     241      {
     242        fprintf (stderr, "tst_cleanup_8 called with wrong data, got \"%s\"\n",
     243  	       (char *)data);
     244        cleanup8_retval = 1;
     245        return;
     246      }
     247  
     248    free (data);
     249  
     250    if (error_status & PAM_DATA_REPLACE)
     251      {
     252        fprintf (stderr, "tst_cleanup_8 called with PAM_DATA_REPLACE set\n");
     253        cleanup8_retval = 1;
     254        return;
     255      }
     256  
     257    if (error_status & PAM_DATA_SILENT)
     258      {
     259        fprintf (stderr, "tst_cleanup_8 called with PAM_DATA_SILENT set\n");
     260        cleanup8_retval = 1;
     261        return;
     262      }
     263  
     264    if (error_status != 987)
     265      {
     266        fprintf (stderr, "tst_cleanup_8 called with wrong error_status set: %d\n",
     267  	       error_status);
     268        cleanup8_retval = 1;
     269        return;
     270      }
     271  }
     272  
     273  int
     274  main (void)
     275  {
     276    const char *service = "dummy";
     277    const char *user = "root";
     278    struct pam_conv conv = { NULL, NULL };
     279    pam_handle_t *pamh;
     280    void *dataptr;
     281    int retval;
     282  
     283    /* 1: Call with NULL as pam handle */
     284    dataptr = strdup ("test1");
     285    retval = pam_set_data (NULL, "tst-pam_set_data-1", dataptr, tst_cleanup);
     286    if (retval == PAM_SUCCESS)
     287      {
     288        fprintf (stderr, "pam_set_data (NULL, ...) returned PAM_SUCCESS\n");
     289        return 1;
     290      }
     291    free (dataptr);
     292  
     293    /* setup pam handle */
     294    retval = pam_start (service, user, &conv, &pamh);
     295    if (retval != PAM_SUCCESS)
     296      {
     297        fprintf (stderr, "pam_start (%s, %s, &conv, &pamh) returned %d\n",
     298                 service, user, retval);
     299        return 1;
     300      }
     301  
     302    /* 2: check for call from application  */
     303    dataptr = strdup ("test2");
     304    retval = pam_set_data (pamh, "tst-pam_set_data-2", dataptr, tst_cleanup);
     305    if (retval != PAM_SYSTEM_ERR)
     306      {
     307        fprintf (stderr,
     308  	       "pam_set_data returned %d when expecting PAM_SYSTEM_ERR\n",
     309  	       retval);
     310        return 1;
     311      }
     312    free (dataptr);
     313  
     314  
     315    /* 3: check for call from module  */
     316    __PAM_TO_MODULE(pamh);
     317    dataptr = strdup ("test3");
     318    retval = pam_set_data (pamh, "tst-pam_set_data-3", dataptr,
     319  			 tst_cleanup_3);
     320    if (retval != PAM_SUCCESS)
     321      {
     322        fprintf (stderr,
     323  	       "pam_set_data failed: %d\n",
     324  	       retval);
     325        return 1;
     326      }
     327  
     328    /* 4: check for call with NULL as module_data_name */
     329    dataptr = strdup ("test4");
     330    retval = pam_set_data (pamh, NULL, dataptr, tst_cleanup);
     331    if (retval == PAM_SUCCESS)
     332      {
     333        fprintf (stderr,
     334  	       "pam_set_data with NULL as module_data_name succeeded!\n");
     335        return 1;
     336      }
     337    free (dataptr);
     338  
     339    /* 5: check for call with NULL as cleanup function */
     340    dataptr = strdup ("test5");
     341    retval = pam_set_data (pamh, "tst-pam_set_data-5", dataptr, NULL);
     342    if (retval != PAM_SUCCESS)
     343      {
     344        fprintf (stderr,
     345  	       "pam_set_data with NULL as cleanup function failed: %d\n",
     346  	       retval);
     347        return 1;
     348      }
     349    free (dataptr);
     350  
     351    /* 6: Overwrite data and check cleanup flags */
     352    dataptr = strdup ("test6a");
     353    retval = pam_set_data (pamh, "tst-pam_set_data-6", dataptr,
     354  			 tst_cleanup_6);
     355    if (retval != PAM_SUCCESS)
     356      {
     357        fprintf (stderr,
     358  	       "test6: first pam_set_data failed: %d\n",
     359  	       retval);
     360        return 1;
     361      }
     362  
     363    dataptr = strdup ("test6b");
     364    retval = pam_set_data (pamh, "tst-pam_set_data-6", dataptr,
     365  			 tst_cleanup_6);
     366    if (retval != PAM_SUCCESS)
     367      {
     368        fprintf (stderr,
     369  	       "test6: second pam_set_data failed: %d\n",
     370  	       retval);
     371        return 1;
     372      }
     373  
     374    /* 7: Overwrite data and cleanup function, check cleanup flags */
     375    dataptr = strdup ("test7a");
     376    retval = pam_set_data (pamh, "tst-pam_set_data-7", dataptr,
     377  			 tst_cleanup_7);
     378    if (retval != PAM_SUCCESS)
     379      {
     380        fprintf (stderr,
     381  	       "test7: first pam_set_data failed: %d\n",
     382  	       retval);
     383        return 1;
     384      }
     385  
     386    dataptr = strdup ("test7b");
     387    retval = pam_set_data (pamh, "tst-pam_set_data-7", dataptr,
     388  			 tst_cleanup_7b);
     389    if (retval != PAM_SUCCESS)
     390      {
     391        fprintf (stderr,
     392  	       "test7: second pam_set_data failed: %d\n",
     393  	       retval);
     394        return 1;
     395      }
     396  
     397    __PAM_TO_APP(pamh);
     398  
     399    /* Close PAM handle and check return codes of cleanup functions */
     400    retval = pam_end (pamh, 0);
     401    if (retval != PAM_SUCCESS)
     402      {
     403        fprintf (stderr,
     404  	       "pam_end reported an error: %d\n",
     405  	       retval);
     406        return 1;
     407      }
     408  
     409    if (cleanup_was_called == 1)
     410      return 1;
     411  
     412    if (cleanup3_was_called == 0)
     413      {
     414        fprintf (stderr, "tst_cleanup_3 was never called!\n");
     415        return 1;
     416      }
     417    if (cleanup3_retval != 0)
     418      return 1;
     419  
     420    if (cleanup6_was_called == 0)
     421      {
     422        fprintf (stderr, "tst_cleanup_6 was never called!\n");
     423        return 1;
     424      }
     425    if (cleanup6_retval != 0)
     426      return 1;
     427  
     428    if (cleanup7_was_called == 0)
     429      {
     430        fprintf (stderr, "tst_cleanup_7 was never called!\n");
     431        return 1;
     432      }
     433    if (cleanup7_retval != 0)
     434      return 1;
     435  
     436    if (cleanup7b_was_called == 0)
     437      {
     438        fprintf (stderr, "tst_cleanup_7b was never called!\n");
     439        return 1;
     440      }
     441    if (cleanup7b_retval != 0)
     442      return 1;
     443  
     444    /* test if error code is delivered to cleanup function */
     445    /* setup pam handle */
     446    retval = pam_start (service, user, &conv, &pamh);
     447    if (retval != PAM_SUCCESS)
     448      {
     449        fprintf (stderr, "pam_start (%s, %s, &conv, &pamh) returned %d\n",
     450                 service, user, retval);
     451        return 1;
     452      }
     453  
     454    /* 8: check if cleanup function is called with correct error code */
     455    __PAM_TO_MODULE(pamh);
     456    dataptr = strdup ("test8");
     457    retval = pam_set_data (pamh, "tst-pam_set_data-8", dataptr,
     458  			 tst_cleanup_8);
     459    if (retval != PAM_SUCCESS)
     460      {
     461        fprintf (stderr,
     462  	       "test8: pam_set_data failed: %d\n",
     463  	       retval);
     464        return 1;
     465      }
     466  
     467    __PAM_TO_APP(pamh);
     468  
     469    retval = pam_end (pamh, 987);
     470    if (retval != PAM_SUCCESS)
     471      {
     472        fprintf (stderr,
     473  	       "pam_end reported an error: %d\n",
     474  	       retval);
     475        return 1;
     476      }
     477  
     478    if (cleanup8_was_called == 0)
     479      {
     480        fprintf (stderr, "tst_cleanup_3 was never called!\n");
     481        return 1;
     482      }
     483  
     484    if (cleanup8_retval != 0)
     485      return 1;
     486  
     487    return 0;
     488  }