1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright 2017 Nexenta Systems, Inc.  All rights reserved.
  25  */
  26 
  27 /*
  28  * Client-side interface to the IO Daemon (IOD)
  29  */
  30 
  31 #include <errno.h>
  32 #include <fcntl.h>
  33 #include <stdio.h>
  34 #include <string.h>
  35 #include <strings.h>
  36 #include <stdlib.h>
  37 #include <unistd.h>
  38 #include <netdb.h>
  39 #include <libintl.h>
  40 #include <thread.h>
  41 
  42 #include <sys/byteorder.h>
  43 #include <sys/types.h>
  44 #include <sys/fcntl.h>
  45 #include <sys/ioctl.h>
  46 #include <sys/time.h>
  47 #include <sys/socket.h>
  48 
  49 #include <netinet/in.h>
  50 #include <netinet/tcp.h>
  51 #include <arpa/inet.h>
  52 
  53 #include <netsmb/smb_lib.h>
  54 #include <netsmb/netbios.h>
  55 #include <netsmb/nb_lib.h>
  56 #include <netsmb/smb_dev.h>
  57 
  58 #include <assert.h>
  59 
  60 #include "smb/charsets.h"
  61 #include "smb/private.h"
  62 
  63 /*
  64  * Make sure we don't call the real IOD here.
  65  */
  66 int
  67 smb_iod_open_door(int *fdp)
  68 {
  69         *fdp = -1;
  70         return (ENOTSUP);
  71 }
  72 
  73 /*
  74  * Get a door handle to the IOD...
  75  */
  76 int
  77 smb_iod_start(smb_ctx_t *ctx)
  78 {
  79 
  80         return (0);
  81 }
  82 
  83 void *
  84 iod_work(void *arg)
  85 {
  86         smb_ctx_t *ctx = arg;
  87         (void) smb_iod_work(ctx);
  88         smb_ctx_free(ctx);
  89         return (NULL);
  90 }
  91 
  92 /*
  93  * Ask the IOD to connect using the info in ctx.
  94  * Called by newvc.
  95  *
  96  * This function largely follows smbiod.c : iod_newvc()
  97  */
  98 int
  99 smb_iod_cl_newvc(smb_ctx_t *cl_ctx)
 100 {
 101         smb_ctx_t *ctx;
 102         thread_t tid;
 103         int err = 0;
 104 
 105         /*
 106          * Clone the context, like in smbiod.c
 107          */
 108         err = smb_ctx_alloc(&ctx);
 109         if (err)
 110                 return (err);
 111         bcopy(&cl_ctx->ct_iod_ssn, &ctx->ct_iod_ssn,
 112             sizeof (ctx->ct_iod_ssn));
 113 
 114         /*
 115          * Create the driver session first...
 116          */
 117         if ((err = smb_ctx_gethandle(ctx)) != 0)
 118                 goto out;
 119         if (nsmb_ioctl(ctx->ct_dev_fd, SMBIOC_SSN_CREATE, &ctx->ct_ssn) < 0) {
 120                 err = errno;
 121                 if (err == EEXIST)
 122                         err = 0; /* see above */
 123                 goto out;
 124         }
 125 
 126         /*
 127          * Do the initial connection setup here, so we can
 128          * report the outcome to the door client.
 129          */
 130         err = smb_iod_connect(ctx);
 131         if (err != 0) {
 132                 fprintf(stderr, "smb_iod_connect, err=%d\n", err);
 133                 goto out;
 134         }
 135 
 136         /* The rest happens in the iod_work thread. */
 137         err = thr_create(NULL, 0, iod_work, ctx, THR_DETACHED, &tid);
 138         if (err == 0) {
 139                 /*
 140                  * Given to the new thread.
 141                  * free at end of iod_work
 142                  */
 143                 ctx = NULL;
 144         }
 145 
 146 out:
 147         if (ctx != NULL)
 148                 smb_ctx_free(ctx);
 149 
 150         return (err);
 151 }