Home | History | Annotate | Download | only in solaris
      1 /* Tests for name switch cache daemon (nscd) door wrapper. */
      2 
      3 #include "config.h"
      4 
      5 #include <assert.h>
      6 #include <ctype.h>
      7 #include <door.h>
      8 #include <fcntl.h>
      9 #include <inttypes.h>
     10 #include <nss_dbdefs.h>
     11 #include <stdio.h>
     12 #include <stdlib.h>
     13 #include <strings.h>
     14 #include <unistd.h>
     15 #include <sys/mman.h>
     16 
     17 #if defined(SOLARIS_NSCD_DOOR_SYSTEM_VOLATILE)
     18 #define DOOR_FILE "/system/volatile/name_service_door"
     19 #else
     20 #define DOOR_FILE "/var/run/name_service_door"
     21 #endif
     22 
     23 #define HEADER(file, test_name) \
     24    fprintf(file, "---------------------------------------------------------\n"  \
     25                  "%s\n"                                                         \
     26                  "---------------------------------------------------------\n", \
     27                  test_name);
     28 
     29 
     30 static long x0;
     31 
     32 /* It's possible that the system allocated a new memory for rbuf.
     33    Unmap it if it is the case. */
     34 static int handle_rbuf(door_arg_t *params, void *buf)
     35 {
     36    if (params->rbuf != buf) {
     37       if (munmap(params->rbuf, params->rsize) != 0) {
     38          perror("munmap");
     39          return EINVAL;
     40       }
     41    }
     42 
     43    return 0;
     44 }
     45 
     46 __attribute__((noinline))
     47 static int test_app_small_request(int did)
     48 {
     49    /* Set call parameters. */
     50    size_t buf_size = sizeof(uint32_t);
     51    char *buf = malloc(buf_size);
     52    assert(buf != NULL);
     53 
     54    nss_pheader_t *header = (nss_pheader_t *) buf;
     55    header->nsc_callnumber = x0 + NSCD_GETENT;
     56 
     57    door_arg_t params;
     58    params.data_ptr = buf;
     59    params.data_size = buf_size;
     60    params.desc_ptr = NULL;
     61    params.desc_num = 0;
     62    params.rbuf = buf;
     63    params.rsize = buf_size;
     64 
     65    /* Make the call. */
     66    if (door_call(did, &params) != 0) {
     67       return errno;
     68    }
     69 
     70    return handle_rbuf(&params, buf);
     71 }
     72 
     73 __attribute__((noinline))
     74 static int test_app_uninitialized_request(int did)
     75 {
     76    /* Set call parameters. */
     77    size_t buf_size = sizeof(nss_pheader_t) + sizeof(nss_dbd_t);
     78    char *buf = malloc(buf_size);
     79    assert(buf != NULL);
     80 
     81    nss_pheader_t *header = (nss_pheader_t *) buf;
     82    header->nsc_callnumber = x0 + NSCD_GETENT;
     83    header->dbd_off = x0 + sizeof(nss_pheader_t);
     84    header->dbd_len = x0 + sizeof(nss_dbd_t);
     85    nss_dbd_t *dbd = (nss_dbd_t *) (buf + sizeof(nss_pheader_t));
     86    dbd->flags = x0;
     87    dbd->o_name = x0 + 100;
     88    dbd->o_config_name = x0 + 100;
     89    dbd->o_default_config = x0 + 100;
     90    header->key_off = x0 + sizeof(nss_pheader_t) + sizeof(nss_dbd_t);
     91    header->key_len = x0 + 1; // one byte past the end of 'buf'
     92    header->pbufsiz = x0 + 10000000;
     93 
     94    door_arg_t params;
     95    params.data_ptr = buf;
     96    params.data_size = buf_size;
     97    params.desc_ptr = NULL;
     98    params.desc_num = 0;
     99    params.rbuf = buf;
    100    params.rsize = buf_size;
    101 
    102    /* Make the call. */
    103    if (door_call(did, &params) != 0) {
    104       return errno;
    105    }
    106 
    107    /* Check definedness of response attributes ... */
    108    int x = 0;
    109    if (header->p_status != NSS_SUCCESS) x = -1; else x = -2;
    110    if (header->p_herrno != 0) x = -2; else x = -3;
    111    if (header->key_off != 0) x = -4; else x = -5;
    112    if (header->key_len != 0) x = -6; else x = -7;
    113    if (header->data_off != 0) x = -8; else x = -9;
    114    if (header->data_len != 0) x = -10; else x = -11;
    115    /* ... and now one which is not defined. */
    116    if (header->reserved1 != 0) x = -12; else x = -13;
    117 
    118    handle_rbuf(&params, buf);
    119    return x;
    120 }
    121 
    122 __attribute__((noinline))
    123 static int test_app_proto_icmp(int did)
    124 {
    125    door_arg_t params;
    126    char buf[16384];
    127 
    128    /* Set call parameters. */
    129    nss_pheader_t *header = (nss_pheader_t *) buf;
    130    header->nsc_callnumber = NSCD_SEARCH;
    131    header->p_ruid = getuid();
    132    header->p_euid = geteuid();
    133    header->p_version = NSCD_HEADER_REV;
    134    header->p_status = 0;
    135    header->p_errno = 0;
    136    header->p_herrno = 0;
    137    header->libpriv = 0;
    138    header->nss_dbop = NSS_DBOP_PROTOCOLS_BYNAME;
    139 
    140    size_t name_len = strlen(NSS_DBNAM_PROTOCOLS);
    141    size_t default_config_len = strlen(NSS_FILES_ONLY);
    142    header->dbd_off = sizeof(nss_pheader_t);
    143    header->dbd_len = sizeof(nss_dbd_t) + name_len + 1 + default_config_len + 1;
    144    nss_dbd_t *dbd = (nss_dbd_t *) (buf + sizeof(nss_pheader_t));
    145    dbd->o_name = sizeof(nss_dbd_t);
    146    dbd->o_config_name = 0;
    147    dbd->o_default_config = dbd->o_name + name_len + 1;
    148    dbd->flags = 0;
    149    strcpy(buf + header->dbd_off + dbd->o_name, NSS_DBNAM_PROTOCOLS);
    150    strcpy(buf + header->dbd_off + dbd->o_default_config,
    151           NSS_DEFCONF_PROTOCOLS);
    152 
    153    name_len = strlen("icmp");
    154    header->key_off = header->dbd_off + ROUND_UP(header->dbd_len, sizeof(nssuint_t));
    155    header->key_len = name_len + 1;
    156    strcpy(buf + header->key_off, "icmp");
    157 
    158    header->data_off = header->key_off + ROUND_UP(header->key_len, sizeof(nssuint_t));
    159    header->data_len = 0;
    160    header->pbufsiz = header->data_off + header->data_len;
    161 
    162    params.data_ptr = buf;
    163    params.data_size = header->pbufsiz;
    164    params.desc_ptr = NULL;
    165    params.desc_num = 0;
    166    params.rbuf = buf;
    167    params.rsize = sizeof(buf);
    168 
    169    /* Sanity checks on the nss_pheader_t header. */
    170    assert(header->p_version == NSCD_HEADER_REV);
    171    assert(header->dbd_off == sizeof(nss_pheader_t));
    172    assert((params.data_size & 3) == 0);
    173    assert((header->dbd_off & 3) == 0);
    174    assert((header->key_off & 3) == 0);
    175    assert((header->data_off & 3) == 0);
    176    assert(header->data_off == params.data_size);
    177    nssuint_t l1 = header->key_off - header-> dbd_off;
    178    assert(l1 >= header->dbd_len);
    179    nssuint_t l2 = header->data_off - header->key_off;
    180    assert(l2 >= header->key_len);
    181    assert(sizeof(nss_pheader_t) + l1 + l2 == header->data_off);
    182    assert(header->data_off + header->data_len == header->pbufsiz);
    183 
    184    /* Make the call. */
    185    if (door_call(did, &params) != 0) {
    186       return errno;
    187    }
    188 
    189    /* Print response attributes. */
    190    HEADER(stdout, "app_proto_icmp");
    191    printf("status=%u\n", header->p_status);
    192    printf("errno=%u\n", header->p_errno);
    193    printf("herrno=%u\n", header->p_herrno);
    194    printf("bufsiz=%" PRIu64 "\n", header->pbufsiz);
    195    printf("dbd_off=%" PRIu64 " dbd_len=%" PRIu64 "\n",
    196           header->dbd_off, header->dbd_len);
    197    printf("key_off=%" PRIu64 " key_len=%" PRIu64 "\n",
    198           header->key_off, header->key_len);
    199    printf("data_off=%" PRIu64 " data_len=%" PRIu64 "\n",
    200           header->data_off, header->data_len);
    201    printf("ext_off=%" PRIu64 " ext_len=%" PRIu64 "\n",
    202           header->ext_off, header->ext_len);
    203    printf("key=%s\n", buf + header->key_off);
    204 
    205    /* Parse response proto data. */
    206    char *p = buf + header->data_off;
    207    char *limit = p + header->data_len;
    208 
    209    while ((p < limit) && isspace(*p))
    210       p++;
    211    char *name_start = p;
    212    while ((p < limit) && !isspace(*p))
    213       p++; // skip over the name
    214    name_len = p - name_start;
    215 
    216    while ((p < limit) && isspace(*p))
    217       p++;
    218    char *number_start = p;
    219    do {
    220       p++; // skip over the proto number
    221    } while ((p < limit) && !isspace(*p));
    222    size_t number_len = p - number_start;
    223 
    224    while ((p < limit) && isspace(*p))
    225       p++;
    226    char *aliases_start = p;
    227    while ((p < limit) && !isspace(*p))
    228       p++; // skip over the aliases
    229    size_t aliases_len = p - aliases_start;
    230 
    231    printf("data: name=%.*s number=%.*s aliases=%.*s\n",
    232       (int) name_len, name_start, (int) number_len, number_start,
    233       (int) aliases_len, aliases_start);
    234 
    235    return handle_rbuf(&params, buf);
    236 }
    237 
    238 int main(int argc, const char *argv[])
    239 {
    240    /* Uninitialised, but we know px[0] is 0x0. */
    241    long *px = malloc(sizeof(long));
    242    x0 = px[0];
    243 
    244    int did = open(DOOR_FILE, O_RDONLY);
    245    if (did < 0) {
    246       perror("open " DOOR_FILE);
    247       fprintf(stderr, "Make sure the name service switch daemon (nscd) "
    248               "is running.\n");
    249       return 1;
    250    }
    251 
    252    struct door_info info;
    253    if (door_info(did, &info) != 0) {
    254       perror("door_info " DOOR_FILE);
    255       close(did);
    256       return 1;
    257    }
    258 
    259    HEADER(stderr, "app_small_request");
    260    test_app_small_request(did);
    261 
    262    HEADER(stderr, "app_uninitialized_request");
    263    test_app_uninitialized_request(did);
    264 
    265    HEADER(stderr, "app_proto_icmp");
    266    test_app_proto_icmp(did);
    267 
    268    close(did);
    269 
    270    return 0;
    271 }
    272 
    273