Esempio n. 1
0
static int smb_connect( stream_t *p_access, const char *psz_login,
                        const char *psz_password, const char *psz_domain)
{
    access_sys_t *p_sys = p_access->p_sys;

    smb_session_set_creds( p_sys->p_session, psz_domain,
                           psz_login, psz_password );
    if( smb_session_login( p_sys->p_session ) == DSM_SUCCESS )
    {
        if( p_sys->psz_share )
        {
            /* Connect to the share */
            if( smb_tree_connect( p_sys->p_session, p_sys->psz_share,
                                  &p_sys->i_tid ) != DSM_SUCCESS )
                return VLC_EGENERIC;

            /* Let's finally ask a handle to the file we wanna read ! */
            return smb_fopen( p_sys->p_session, p_sys->i_tid, p_sys->psz_path,
                              SMB_MOD_RO, &p_sys->i_fd )
                              == DSM_SUCCESS ? VLC_SUCCESS : VLC_EGENERIC;
        }
        else
            return VLC_SUCCESS;
    }
    else
        return VLC_EGENERIC;
}
Esempio n. 2
0
int main()
{
  struct in_addr  addr;
  smb_session   *session;
  smb_tid     tid;
  smb_fd      fd;

  session = smb_session_new();
  if (session == NULL)
    exit(1);

  inet_aton("127.0.0.1", &addr.sin_addr);

  if (smb_session_connect(session, "MYNAME", 
      addr.sin_addr.s_addr, SMB_TRANSPORT_TCP))
  {
    printf("Unable to connect to host\n");
    exit(2);
  }

  smb_session_set_creds(session, "MYNAME", "login", 
              "password");
  if (smb_session_login(session))
  {
    if (session->guest)
      printf("Logged in as GUEST \n");
    else
      printf("Successfully logged in\n");
  }
  else
  {
    printf("Auth failed\n");
    exit(3);
  }

  tid = smb_tree_connect(session, "MyShare");
  if (!tid)
  {
    printf("Unable to connect to share\n");
    exit(4);
  }

  fd = smb_fopen(session, tid, "\\My\\File");
  if (!fd)
  {
    printf("Unable to open file\n");
    exit(5);
  }

  char buffer[512];
  smb_fread(session, fd, buffer, 512);

  /* Use data */

  smb_fclose(session, fd);
  smb_tree_disconnect(session, tid);
  smb_session_destroy(session);

  return(0);
}
Esempio n. 3
0
static int smb_connect( access_t *p_access, const char *psz_login,
                        const char *psz_password, const char *psz_domain )
{
    access_sys_t *p_sys = p_access->p_sys;

    smb_session_set_creds( p_sys->p_session, psz_domain,
                           psz_login, psz_password );
    if( smb_session_login( p_sys->p_session ) )
    {
        if( p_sys->psz_share )
        {
            /* Connect to the share */
            p_sys->i_tid = smb_tree_connect( p_sys->p_session, p_sys->psz_share );
            if( !p_sys->i_tid )
                return VLC_EGENERIC;

            /* Let's finally ask a handle to the file we wanna read ! */
            p_sys->i_fd = smb_fopen( p_sys->p_session, p_sys->i_tid,
                                     p_sys->psz_path, SMB_MOD_RO );
            /* TODO: fix smb_fopen to return a specific error code in case of
             * wrong permissions */
            return p_sys->i_fd > 0 ? VLC_SUCCESS : VLC_EGENERIC;
        }
        else
            return VLC_SUCCESS;
    }
    else
        return VLC_EGENERIC;
}
Esempio n. 4
0
static int smb_connect( access_t *p_access )
{
    access_sys_t *p_sys = p_access->p_sys;
    const char *psz_login = p_sys->creds.login ?
                            p_sys->creds.login : "******";
    const char *psz_password = p_sys->creds.password ?
                               p_sys->creds.password : "******";
    const char *psz_domain = p_sys->creds.domain ?
                             p_sys->creds.domain : p_sys->netbios_name;

    smb_session_set_creds( p_sys->p_session, psz_domain,
                           psz_login, psz_password );
    if( smb_session_login( p_sys->p_session ) )
    {
        if( p_sys->psz_share )
        {
            /* Connect to the share */
            p_sys->i_tid = smb_tree_connect( p_sys->p_session, p_sys->psz_share );
            if( !p_sys->i_tid )
                return VLC_EGENERIC;
        }
        return VLC_SUCCESS;
    }
    else
        return VLC_EGENERIC;
}
Esempio n. 5
0
static int ejs_cli_tree_connect(MprVarHandle eid, int argc, MprVar **argv)
{
	struct smbcli_session *session;
	struct smbcli_tree *tree;
	union smb_tcon tcon;
	TALLOC_CTX *mem_ctx;
	NTSTATUS status;
	const char *password = "";

	/* Argument parsing */

	if (argc != 2) {
		ejsSetErrorMsg(eid, "tree_connect invalid arguments");
		return -1;
	}

	if (!mprVarIsPtr(argv[0]->type)) {
		ejsSetErrorMsg(eid, "first arg is not a session handle");
		return -1;
	}

	session = argv[0]->ptr;
	tree = smbcli_tree_init(session, session, False);

	if (!tree) {
		ejsSetErrorMsg(eid, "tree init failed");
		return -1;
	}

	mem_ctx = talloc_init("tcon");
	if (!mem_ctx) {
		ejsSetErrorMsg(eid, "talloc_init failed");
		return -1;
	}

	/* Do tree connect */

	tcon.generic.level = RAW_TCON_TCONX;
	tcon.tconx.in.flags = 0;

	if (session->transport->negotiate.sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) {
		tcon.tconx.in.password = data_blob(NULL, 0);
	} else if (session->transport->negotiate.sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) {
		tcon.tconx.in.password = data_blob_talloc(mem_ctx, NULL, 24);
		if (session->transport->negotiate.secblob.length < 8) {
			ejsSetErrorMsg(eid, "invalid security blob");
			return -1;
		}
		SMBencrypt(password, session->transport->negotiate.secblob.data, tcon.tconx.in.password.data);
	} else {
		tcon.tconx.in.password = data_blob_talloc(mem_ctx, password, strlen(password)+1);
	}

	tcon.tconx.in.path = argv[1]->string;
	tcon.tconx.in.device = "?????";
	
	status = smb_tree_connect(tree, mem_ctx, &tcon);

	if (!NT_STATUS_IS_OK(status)) {
		ejsSetErrorMsg(eid, "tree_connect: %s", nt_errstr(status));
		return -1;
	}

	tree->tid = tcon.tconx.out.tid;

	talloc_free(mem_ctx);	

	mpr_Return(eid, mprCreatePtrVar(tree));

	return 0;
}
Esempio n. 6
0
// We should normally implement SCERPC and SRVSVC to perform a share list. But
// since these two protocols have no other use for us, we'll do it the trash way
// PS: Worst function _EVER_. I don't understand a bit myself
int             smb_share_get_list(smb_session *s, smb_share_list *list, size_t *pcount)
{
    smb_message           *req, resp;
    smb_trans_req         trans;
    smb_tid               ipc_tid;
    smb_fd                srvscv_fd;
    uint16_t              rpc_len;
    size_t                res, frag_len_cursor;
    ssize_t               count;
    int                   ret;

    assert(s != NULL && list != NULL);

    if(s != NULL && list != NULL) {

        *list = NULL;

        if ((ret = smb_tree_connect(s, "IPC$", &ipc_tid)) != DSM_SUCCESS)
            return ret;

        if ((ret = smb_fopen(s, ipc_tid, "\\srvsvc", SMB_MOD_READ | SMB_MOD_WRITE,
                             &srvscv_fd)) != DSM_SUCCESS)
            return ret;

        //// Phase 1:
        // We bind a context or whatever for DCE/RPC

        req = smb_message_new(SMD_CMD_TRANS);
        if (!req)
        {
            ret = DSM_ERROR_GENERIC;
            goto error;
        }
        req->packet->header.tid = ipc_tid;

        rpc_len = 0xffff;
        SMB_MSG_INIT_PKT(trans);
        trans.wct                    = 16;
        trans.total_data_count       = 72;
        trans.max_data_count         = rpc_len;
        trans.param_offset           = 84;
        trans.data_count             = 72;
        trans.data_offset            = 84;
        trans.setup_count            = 2;
        trans.pipe_function          = 0x26;
        trans.fid                    = SMB_FD_FID(srvscv_fd);
        trans.bct                    = 89;
        SMB_MSG_PUT_PKT(req, trans);

        smb_message_put8(req, 0);   // Padding
        smb_message_put_utf16(req, "\\PIPE\\", strlen("\\PIPE\\") + 1);
        smb_message_put16(req, 0);  // Padding to be aligned with wtf boundary :-/

        // Now we'll 'build' the DCE/RPC Packet. This basically a copycat
        // from wireshark values.
        smb_message_put8(req, 5);     // version major
        smb_message_put8(req, 0);     // minor
        smb_message_put8(req, 0x0b);  // Packet type = 'bind'
        smb_message_put8(req, 0x03);  // Packet flags = ??
        smb_message_put32(req, 0x10); // Representation = little endian/ASCII. Damn
        smb_message_put16(req, 72);   // Data len again
        smb_message_put16(req, 0);    // Auth len ?
        smb_message_put32(req, 19);   // Call ID ?
        smb_message_put16(req, rpc_len);      // Max Xmit size
        smb_message_put16(req, rpc_len);      // Max Recv size
        smb_message_put32(req, 0);    // Assoc group ?

        smb_message_put32(req, 1);    // Num Ctx Item
        // Adding the CtxItem, whatever could that be
        smb_message_put16(req, 0);    // ContextID
        smb_message_put16(req, 1);    // Num Trans Item
        // SRVSVC UUID
        const uint8_t uuid_e[8] = {0x12, 0x78, 0x5a, 0x47, 0xbf, 0x6e, 0xe1, 0x88};
        smb_message_put_uuid(req, 0x4b324fc8, 0x1670, 0x01d3, uuid_e);
        smb_message_put16(req, 3);    // Version
        smb_message_put16(req, 0);    // Minor
        // Another UUID
        const uint8_t uuid_e2[8] = {0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60};
        smb_message_put_uuid(req, 0x8a885d04, 0x1ceb, 0x11c9, uuid_e2);
        smb_message_put32(req, 2);    // Another version

        // Let's send this ugly pile of shit over the network !
        res = smb_session_send_msg(s, req);
        smb_message_destroy(req);
        if (!res)
        {
            ret = DSM_ERROR_NETWORK;
            goto error;
        }

        // Is the server throwing pile of shit back at me ?
        res = smb_session_recv_msg(s, &resp);
        if (!res || resp.packet->payload[68])
        {
            BDSM_dbg("Bind call failed: 0x%hhx (reason = 0x%hhx)\n",
                     resp.packet->payload[68], resp.packet->payload[70]);
            ret = DSM_ERROR_NETWORK;
            goto error;
        }


        //// Phase 2:
        // Now we have the 'bind' done (regarless of what it is), we'll call
        // NetShareEnumAll

        req = smb_message_new(SMD_CMD_TRANS);
        if (!req)
        {
            ret = DSM_ERROR_GENERIC;
            goto error;
        }
        req->packet->header.tid = ipc_tid;

        // this struct will be set at the end when we know the data size
        SMB_MSG_ADVANCE_PKT(req, smb_trans_req);

        smb_message_put8(req, 0);  // Padding
        smb_message_put_utf16(req, "\\PIPE\\", strlen("\\PIPE\\") + 1);
        smb_message_put16(req, 0); // Padding

        // Now we'll 'build' the DCE/RPC Packet. This basically a copycat
        // from wireshark values.
        smb_message_put8(req, 5);     // version major
        smb_message_put8(req, 0);     // minor
        smb_message_put8(req, 0);     // Packet type = 'request'
        smb_message_put8(req, 0x03);  // Packet flags = ??
        smb_message_put32(req, 0x10); // Representation = little endian/ASCII. Damn
        // Let's save the cursor here to update that later
        frag_len_cursor = req->cursor;
        smb_message_put16(req, 0);    // Data len again (frag length)
        smb_message_put16(req, 0);    // Auth len ?
        smb_message_put32(req, 12);   // Call ID ?
        smb_message_put32(req, 64);   // Alloc hint ?
        smb_message_put16(req, 0);    // Context ID ?
        smb_message_put16(req, 15);   // OpNum = NetShareEnumAll

        // Pointer to server UNC
        smb_message_put32(req, 0x00020000);   // Referent ID ?
        smb_message_put32(req, strlen(s->srv.name) + 1);            // Max count
        smb_message_put32(req, 0);            // Offset
        smb_message_put32(req, strlen(s->srv.name) + 1);            // Actual count
        // The server name, supposed to be downcased
        smb_message_put_utf16(req, s->srv.name, strlen(s->srv.name) + 1);
        if ((strlen(s->srv.name) % 2) == 0) // It won't be aligned with the terminating byte
            smb_message_put16(req, 0);

        smb_message_put32(req, 1);            // Level 1 ?
        smb_message_put32(req, 1);            // Ctr ?
        smb_message_put32(req, 0x00020004);   // Referent ID ?
        smb_message_put64(req, 0);            // Count/Null Pointer to NetShareInfo1
        smb_message_put32(req, 0xffffffff);   // Max Buffer (0xffffffff required by smbX)

        smb_message_put32(req, 0x00020008);   // Referent ID ?
        smb_message_put32(req, 0);            // Resume ?

        // fill trans pkt at the end since we know the size at the end
        SMB_MSG_INIT_PKT(trans);
        trans.wct              = 16;
        trans.max_data_count   = 4280;
        trans.setup_count      = 2;
        trans.pipe_function    = 0x26; // TransactNmPipe;
        trans.fid              = SMB_FD_FID(srvscv_fd);
        trans.bct              = req->cursor - sizeof(smb_trans_req);
        trans.data_count       = trans.bct - 17; // 17 -> padding + \PIPE\ + padding
        trans.total_data_count = trans.data_count;
        trans.data_offset      = 84;
        trans.param_offset     = 84;
        // but insert it at the begining
        SMB_MSG_INSERT_PKT(req, 0, trans);

        req->packet->payload[frag_len_cursor] = trans.data_count; // (data_count SHOULD stay < 256)

        // Let's send this ugly pile of shit over the network !
        res = smb_session_send_msg(s, req);
        smb_message_destroy(req);
        if (!res)
        {
            ret = DSM_ERROR_NETWORK;
            goto error;
        }

        // Is the server throwing pile of shit back at me ?
        res = smb_session_recv_msg(s, &resp);
        if (!res && (uint32_t)resp.packet->payload[resp.payload_size - 4])
        {
            BDSM_dbg("NetShareEnumAll call failed.\n");
            ret = DSM_ERROR_NETWORK;
            goto error;
        }


        //// Phase 3
        // We parse the list of Share (finally !) and build function response
        count = smb_share_parse_enum(&resp, list);
        if (count == -1)
        {
            ret = DSM_ERROR_GENERIC;
            goto error;
        }
        if (pcount != NULL)
            *pcount = count;
        ret = DSM_SUCCESS;

error:
        // Close the pipe
        smb_fclose(s, srvscv_fd);
        return ret;
    }

    ret = DSM_ERROR_GENERIC;
}