Example #1
0
static int				/* O - 0 = success, non-0 = failure */
smb_print(struct cli_state *cli,	/* I - SMB connection */
          char             *title,	/* I - Title/job name */
          FILE             *fp)		/* I - File to print */
{
  int	fnum;		/* File number */
  int	nbytes,		/* Number of bytes read */
	tbytes;		/* Total bytes read */
  char	buffer[8192],	/* Buffer for copy */
	*ptr;		/* Pointer into tile */


 /*
  * Sanitize the title...
  */

  for (ptr = title; *ptr; ptr ++)
    if (!isalnum((int)*ptr) && !isspace((int)*ptr))
      *ptr = '_';

 /*
  * Open the printer device...
  */

  if ((fnum = cli_open(cli, title, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE)) == -1)
  {
    fprintf(stderr, "ERROR: %s opening remote spool %s\n",
            cli_errstr(cli), title);
    return (1);
  }

 /*
  * Copy the file to the printer...
  */

  if (fp != stdin)
    rewind(fp);

  tbytes = 0;

  while ((nbytes = fread(buffer, 1, sizeof(buffer), fp)) > 0)
  {
    if (cli_write(cli, fnum, 0, buffer, tbytes, nbytes) != nbytes)
    {
      fprintf(stderr, "ERROR: Error writing spool: %s\n", cli_errstr(cli));
      break;
    }

    tbytes += nbytes;
  } 

  if (!cli_close(cli, fnum))
  {
    fprintf(stderr, "ERROR: %s closing remote spool %s\n",
            cli_errstr(cli), title);
    return (1);
  }
  else
    return (0);
}
Example #2
0
void send_message(const char *msg) {
	pstring msg_conv;
	int len;
	int grp_id;

	#if SAMBA_VERSION_MAJOR==2
	 #if SAMBA_VERSION_RELEASE < 4
	    /* Samba 2.2.0-2.2.3 */
	    pstrcpy(msg_conv, unix_to_dos(msg, FALSE));
	 #else
	    /* Samba >= 2.2.4 */
	    pstrcpy(msg_conv, unix_to_dos(msg));
         #endif
	#elif SAMBA_VERSION_MAJOR==3
	push_ascii_pstring(msg_conv, msg);
	#endif

	len = strlen(msg_conv);

        if (!cli_message_start(cli, remote_machine, username, &grp_id)) {
                DEBUG(5,("message start: %s\n", cli_errstr(cli)));
                return;
        }

	if (!cli_message_text(cli, msg_conv, len, grp_id)) {
		DEBUG(5,("SMBsendtxt failed: %s\n",cli_errstr(cli)));
		return;
	}

        if (!cli_message_end(cli, grp_id)) {
                DEBUG(5,("SMBsendend failed: %s\n",cli_errstr(cli)));
                return;
        }   
}
Example #3
0
BOOL attempt_netbios_session_request(struct cli_state *cli, const char *srchost, const char *desthost,
                                     struct in_addr *pdest_ip)
{
	struct nmb_name calling, called;

	make_nmb_name(&calling, srchost, 0x0);

	/*
	 * If the called name is an IP address
	 * then use *SMBSERVER immediately.
	 */

	if(is_ipaddress(desthost))
		make_nmb_name(&called, "*SMBSERVER", 0x20);
	else
		make_nmb_name(&called, desthost, 0x20);

	if (!cli_session_request(cli, &calling, &called)) {
	
		struct nmb_name smbservername;

		make_nmb_name(&smbservername , "*SMBSERVER", 0x20);

		/*
		 * If the name wasn't *SMBSERVER then
		 * try with *SMBSERVER if the first name fails.
		 */

		if (nmb_name_equal(&called, &smbservername)) {

			/*
			 * The name used was *SMBSERVER, don't bother with another name.
			 */

			DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name *SMBSERVER with error %s.\n", 
				desthost, cli_errstr(cli) ));
			return False;
		}

		/*
		 * We need to close the connection here but can't call cli_shutdown as
		 * will free an allocated cli struct. cli_close_connection was invented
		 * for this purpose. JRA. Based on work by "Kim R. Pedersen" <*****@*****.**>.
		 */

		cli_close_connection(cli);

		if (!cli_initialise(cli) || !cli_connect(cli, desthost, pdest_ip) ||
       			!cli_session_request(cli, &calling, &smbservername)) {
			DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name *SMBSERVER with error %s\n", 
				desthost, cli_errstr(cli) ));
			return False;
		}
	}

	return True;
}
Example #4
0
bool cli_rpc_pipe_close(struct rpc_pipe_client *cli)
{
	bool ret;

	if (!cli) {
		return false;
	}

	ret = cli_close(cli->cli, cli->fnum);

	if (!ret) {
		DEBUG(1,("cli_rpc_pipe_close: cli_close failed on pipe %s, "
                         "fnum 0x%x "
                         "to machine %s.  Error was %s\n",
                         cli->pipe_name,
                         (int) cli->fnum,
                         cli->cli->desthost,
                         cli_errstr(cli->cli)));
	}

	if (cli->auth.cli_auth_data_free_func) {
		(*cli->auth.cli_auth_data_free_func)(&cli->auth);
	}

	DEBUG(10,("cli_rpc_pipe_close: closed pipe %s to machine %s\n",
		cli->pipe_name, cli->cli->desthost ));

	DLIST_REMOVE(cli->cli->pipe_list, cli);
	talloc_destroy(cli->mem_ctx);
	return ret;
}
Example #5
0
static void send_message(void)
{
	int total_len = 0;
	int grp_id;

	if (!cli_message_start(cli, desthost, username, &grp_id)) {
		d_printf("message start: %s\n", cli_errstr(cli));
		return;
	}


	d_printf("Connected. Type your message, ending it with a Control-D\n");

	while (!feof(stdin) && total_len < 1600) {
		int maxlen = MIN(1600 - total_len,127);
		pstring msg;
		int l=0;
		int c;

		ZERO_ARRAY(msg);

		for (l=0;l<maxlen && (c=fgetc(stdin))!=EOF;l++) {
			if (c == '\n')
				msg[l++] = '\r';
			msg[l] = c;   
		}

		if (!cli_message_text(cli, msg, l, grp_id)) {
			d_printf("SMBsendtxt failed (%s)\n",cli_errstr(cli));
			return;
		}      
		
		total_len += l;
	}

	if (total_len >= 1600)
		d_printf("the message was truncated to 1600 bytes\n");
	else
		d_printf("sent %d bytes\n",total_len);

	if (!cli_message_end(cli, grp_id)) {
		d_printf("SMBsendend failed (%s)\n",cli_errstr(cli));
		return;
	}      
}
Example #6
0
void nb_unlink(const char *fname)
{
	if (!NT_STATUS_IS_OK(cli_unlink(c, fname, aSYSTEM | aHIDDEN))) {
#if NBDEBUG
		printf("(%d) unlink %s failed (%s)\n", 
		       line_count, fname, cli_errstr(c));
#endif
	}
}
Example #7
0
File: nbio.c Project: gojdic/samba
void nb_unlink(const char *fname)
{
	if (!cli_unlink(c, fname)) {
#if NBDEBUG
		printf("(%d) unlink %s failed (%s)\n", 
		       line_count, fname, cli_errstr(c));
#endif
	}
}
Example #8
0
void nb_rmdir(char *fname)
{
	strupper(fname);

	if (!cli_rmdir(c, fname)) {
#if NBDEBUG
		printf("rmdir %s failed (%s)\n", 
		       fname, cli_errstr(c));
#endif
	}
}
Example #9
0
static BOOL gpo_sync_files(struct sync_context *ctx)
{
	DEBUG(3,("calling cli_list with mask: %s\n", ctx->mask));

	if (cli_list(ctx->cli, ctx->mask, ctx->attribute, gpo_sync_func, ctx) == -1) {
		DEBUG(1,("listing [%s] failed with error: %s\n", 
			ctx->mask, cli_errstr(ctx->cli)));
		return False;
	}

	return True;
}
Example #10
0
static void do_setrattr(char *name, uint16 attr, int set)
{
	uint16 oldattr;

	if (!cli_getatr(cli, name, &oldattr, NULL, NULL)) return;

	if (set == ATTRSET) {
		attr |= oldattr;
	} else {
		attr = oldattr & ~attr;
	}

	if (!cli_setatr(cli, name, attr, 0)) {
		DEBUG(1,("setatr failed: %s\n", cli_errstr(cli)));
	}
}
Example #11
0
static int rpc_transport_np_state_destructor(struct rpc_transport_np_state *s)
{
    if (s->cli->fd == -1) {
        DEBUG(10, ("socket was closed, no need to send close request.\n"));
        return 0;
    }

    if (!NT_STATUS_IS_OK(cli_close(s->cli, s->fnum))) {
        DEBUG(1, ("rpc_transport_np_state_destructor: cli_close "
                  "failed on pipe %s. Error was %s\n", s->pipe_name,
                  cli_errstr(s->cli)));
    }
    DEBUG(10, ("rpc_pipe_destructor: closed %s\n", s->pipe_name));
    /*
     * We can't do much on failure
     */
    return 0;
}
Example #12
0
void nb_open(char *fname, int handle, int size)
{
	int fd, i;
	int flags = O_RDWR|O_CREAT;
	size_t st_size;
	static int count;

	strupper(fname);

	if (size == 0) flags |= O_TRUNC;

	fd = cli_open(c, fname, flags, DENY_NONE);
	if (fd == -1) {
#if NBDEBUG
		printf("(%d) open %s failed for handle %d (%s)\n", 
		       line_count, fname, handle, cli_errstr(c));
#endif
		return;
	}
	cli_getattrE(c, fd, NULL, &st_size, NULL, NULL, NULL);
	if (size > st_size) {
#if NBDEBUG
		printf("(%d) needs expanding %s to %d from %d\n", 
		       line_count, fname, size, (int)st_size);
#endif
	} else if (size < st_size) {
#if NBDEBUG
		printf("(%d) needs truncating %s to %d from %d\n", 
		       line_count, fname, size, (int)st_size);
#endif
	}
	for (i=0;i<MAX_FILES;i++) {
		if (ftable[i].handle == 0) break;
	}
	if (i == MAX_FILES) {
		printf("file table full for %s\n", fname);
		exit(1);
	}
	ftable[i].handle = handle;
	ftable[i].fd = fd;
	if (count++ % 100 == 0) {
		printf(".");
	}
}
Example #13
0
void nb_createx(const char *fname, 
		unsigned create_options, unsigned create_disposition, int handle)
{
	uint16_t fd = (uint16_t)-1;
	int i;
	NTSTATUS status;
	uint32 desired_access;

	if (create_options & FILE_DIRECTORY_FILE) {
		desired_access = FILE_READ_DATA;
	} else {
		desired_access = FILE_READ_DATA | FILE_WRITE_DATA;
	}

	status = cli_ntcreate(c, fname, 0, 
				desired_access,
				0x0,
				FILE_SHARE_READ|FILE_SHARE_WRITE, 
				create_disposition, 
				create_options, 0, &fd);
	if (!NT_STATUS_IS_OK(status) && handle != -1) {
		printf("ERROR: cli_ntcreate failed for %s - %s\n",
		       fname, cli_errstr(c));
		exit(1);
	}
	if (NT_STATUS_IS_OK(status) && handle == -1) {
		printf("ERROR: cli_ntcreate succeeded for %s\n", fname);
		exit(1);
	}
	if (fd == (uint16_t)-1) return;

	for (i=0;i<MAX_FILES;i++) {
		if (ftable[i].handle == 0) break;
	}
	if (i == MAX_FILES) {
		printf("(%d) file table full for %s\n", line_count, 
		       fname);
		exit(1);
	}
	ftable[i].handle = handle;
	ftable[i].fd = fd;
}
Example #14
0
File: nbio.c Project: gojdic/samba
void nb_createx(const char *fname, 
		unsigned create_options, unsigned create_disposition, int handle)
{
	int fd, i;
	uint32 desired_access;

	if (create_options & FILE_DIRECTORY_FILE) {
		desired_access = FILE_READ_DATA;
	} else {
		desired_access = FILE_READ_DATA | FILE_WRITE_DATA;
	}

	fd = cli_nt_create_full(c, fname, 0, 
				desired_access,
				0x0,
				FILE_SHARE_READ|FILE_SHARE_WRITE, 
				create_disposition, 
				create_options, 0);
	if (fd == -1 && handle != -1) {
		printf("ERROR: cli_nt_create_full failed for %s - %s\n",
		       fname, cli_errstr(c));
		exit(1);
	}
	if (fd != -1 && handle == -1) {
		printf("ERROR: cli_nt_create_full succeeded for %s\n", fname);
		exit(1);
	}
	if (fd == -1) return;

	for (i=0;i<MAX_FILES;i++) {
		if (ftable[i].handle == 0) break;
	}
	if (i == MAX_FILES) {
		printf("(%d) file table full for %s\n", line_count, 
		       fname);
		exit(1);
	}
	ftable[i].handle = handle;
	ftable[i].fd = fd;
}
Example #15
0
static BOOL rpc_api_pipe(struct cli_state *cli, prs_struct *data, prs_struct *rdata,
			 uint8 expected_pkt_type)
{
	uint32 len;
	char *rparam = NULL;
	uint32 rparam_len = 0;
	uint16 setup[2];
	BOOL first = True;
	BOOL last  = True;
	RPC_HDR rhdr;
	char *pdata = data ? prs_data_p(data) : NULL;
	uint32 data_len = data ? prs_offset(data) : 0;
	char *prdata = NULL;
	uint32 rdata_len = 0;
	uint32 current_offset = 0;
	uint32 fragment_start = 0;
	uint32 max_data = cli->max_xmit_frag ? cli->max_xmit_frag : 1024;
	int auth_padding_len = 0;

	/* Create setup parameters - must be in native byte order. */

	setup[0] = TRANSACT_DCERPCCMD; 
	setup[1] = cli->nt_pipe_fnum; /* Pipe file handle. */

	DEBUG(5,("rpc_api_pipe: fnum:%x\n", (int)cli->nt_pipe_fnum));

	/* Send the RPC request and receive a response.  For short RPC
	   calls (about 1024 bytes or so) the RPC request and response
	   appears in a SMBtrans request and response.  Larger RPC
	   responses are received further on. */

	if (!cli_api_pipe(cli, "\\PIPE\\",
	          setup, 2, 0,                     /* Setup, length, max */
	          NULL, 0, 0,                      /* Params, length, max */
	          pdata, data_len, max_data,   	   /* data, length, max */
	          &rparam, &rparam_len,            /* return params, len */
	          &prdata, &rdata_len))            /* return data, len */
	{
		DEBUG(0, ("cli_pipe: return critical error. Error was %s\n", cli_errstr(cli)));
		return False;
	}

	/* Throw away returned params - we know we won't use them. */

	SAFE_FREE(rparam);

	if (prdata == NULL) {
		DEBUG(0,("rpc_api_pipe: pipe %x failed to return data.\n",
			(int)cli->nt_pipe_fnum));
		return False;
	}

	/*
	 * Give this memory as dynamically allocated to the return parse
	 * struct.  
	 */

	prs_give_memory(rdata, prdata, rdata_len, True);
	current_offset = rdata_len;

	/* This next call sets the endian bit correctly in rdata. */

	if (!rpc_check_hdr(rdata, &rhdr, &first, &last, &len)) {
		prs_mem_free(rdata);
		return False;
	}

	if (rhdr.pkt_type == RPC_BINDACK) {
		if (!last && !first) {
			DEBUG(5,("rpc_api_pipe: bug in server (AS/U?), setting fragment first/last ON.\n"));
			first = True;
			last = True;
		}
	}

	if (rhdr.pkt_type == RPC_BINDNACK) {
		DEBUG(3, ("Bind NACK received on pipe %x!\n", (int)cli->nt_pipe_fnum));
		prs_mem_free(rdata);
		return False;
	}

	if (rhdr.pkt_type == RPC_RESPONSE) {
		RPC_HDR_RESP rhdr_resp;
		if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, rdata, 0)) {
			DEBUG(5,("rpc_api_pipe: failed to unmarshal RPC_HDR_RESP.\n"));
			prs_mem_free(rdata);
			return False;
		}
	}

	if (rhdr.pkt_type != expected_pkt_type) {
		DEBUG(3, ("Connection to pipe %x got an unexpected RPC packet type - %d, not %d\n", (int)cli->nt_pipe_fnum, rhdr.pkt_type, expected_pkt_type));
		prs_mem_free(rdata);
		return False;
	}

	DEBUG(5,("rpc_api_pipe: len left: %u smbtrans read: %u\n",
	          (unsigned int)len, (unsigned int)rdata_len ));

	/* check if data to be sent back was too large for one SMBtrans */
	/* err status is only informational: the _real_ check is on the
           length */

	if (len > 0) { 
		/* || err == (0x80000000 | STATUS_BUFFER_OVERFLOW)) */

		/* Read the remaining part of the first response fragment */

		if (!rpc_read(cli, rdata, len, &current_offset)) {
			prs_mem_free(rdata);
			return False;
		}
	}

	/*
	 * Now we have a complete PDU, check the auth struct if any was sent.
	 */

	if(!rpc_auth_pipe(cli, rdata, fragment_start, rhdr.frag_len,
			  rhdr.auth_len, rhdr.pkt_type, &auth_padding_len)) {
		prs_mem_free(rdata);
		return False;
	}

	if (rhdr.auth_len != 0) {
		/*
		 * Drop the auth footers from the current offset.
		 * We need this if there are more fragments.
		 * The auth footers consist of the auth_data and the
		 * preceeding 8 byte auth_header.
		 */
		current_offset -= (auth_padding_len + RPC_HDR_AUTH_LEN + rhdr.auth_len);
	}
	
	/* 
	 * Only one rpc fragment, and it has been read.
	 */

	if (first && last) {
		DEBUG(6,("rpc_api_pipe: fragment first and last both set\n"));
		return True;
	}

	/*
	 * Read more fragments using SMBreadX until we get one with the
	 * last bit set.
	 */

	while (!last) {
		RPC_HDR_RESP rhdr_resp;
		int num_read;
		char hdr_data[RPC_HEADER_LEN+RPC_HDR_RESP_LEN];
		prs_struct hps;
		uint8 eclass;
		uint32 ecode;
		
		/*
		 * First read the header of the next PDU.
		 */

		prs_init(&hps, 0, cli->mem_ctx, UNMARSHALL);
		prs_give_memory(&hps, hdr_data, sizeof(hdr_data), False);

		num_read = cli_read(cli, cli->nt_pipe_fnum, hdr_data, 0, RPC_HEADER_LEN+RPC_HDR_RESP_LEN);
		if (cli_is_dos_error(cli)) {
                        cli_dos_error(cli, &eclass, &ecode);
                        if (eclass != ERRDOS && ecode != ERRmoredata) {
                                DEBUG(0,("rpc_api_pipe: cli_read error : %d/%d\n", eclass, ecode));
                                return False;
                        }
		}

		DEBUG(5,("rpc_api_pipe: read header (size:%d)\n", num_read));

		if (num_read != RPC_HEADER_LEN+RPC_HDR_RESP_LEN) {
			DEBUG(0,("rpc_api_pipe: Error : requested %d bytes, got %d.\n",
				RPC_HEADER_LEN+RPC_HDR_RESP_LEN, num_read ));
			return False;
		}

		/* This call sets the endianness in hps. */

		if (!rpc_check_hdr(&hps, &rhdr, &first, &last, &len))
			return False;

		/* Ensure the endianness in rdata is set correctly - must be same as hps. */

		if (hps.bigendian_data != rdata->bigendian_data) {
			DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to %s\n",
				rdata->bigendian_data ? "big" : "little",
				hps.bigendian_data ? "big" : "little" ));
			return False;
		}

		if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, &hps, 0)) {
			DEBUG(0,("rpc_api_pipe: Error in unmarshalling RPC_HDR_RESP.\n"));
			return False;
		}

		if (first) {
			DEBUG(0,("rpc_api_pipe: secondary PDU rpc header has 'first' set !\n"));
			return False;
		}

		/*
		 * Now read the rest of the PDU.
		 */

		if (!rpc_read(cli, rdata, len, &current_offset)) {
			prs_mem_free(rdata);
			return False;
		}

		fragment_start = current_offset - len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;

		/*
		 * Verify any authentication footer.
		 */

		
		if(!rpc_auth_pipe(cli, rdata, fragment_start, rhdr.frag_len,
				  rhdr.auth_len, rhdr.pkt_type, &auth_padding_len)) {
			prs_mem_free(rdata);
			return False;
		}
		
		if (rhdr.auth_len != 0 ) {
			
			/*
			 * Drop the auth footers from the current offset.
			 * The auth footers consist of the auth_data and the
			 * preceeding 8 byte auth_header.
			 * We need this if there are more fragments.
			 */
			current_offset -= (auth_padding_len + RPC_HDR_AUTH_LEN + rhdr.auth_len);
		}
	}

	return True;
}
Example #16
0
static struct cli_state *server_cryptkey(TALLOC_CTX *mem_ctx)
{
	struct cli_state *cli = NULL;
	fstring desthost;
	struct in_addr dest_ip;
	const char *p;
	char *pserver;
	BOOL connected_ok = False;

	if (!(cli = cli_initialise()))
		return NULL;

	/* security = server just can't function with spnego */
	cli->use_spnego = False;

        pserver = talloc_strdup(mem_ctx, lp_passwordserver());
	p = pserver;

        while(next_token( &p, desthost, LIST_SEP, sizeof(desthost))) {
		standard_sub_basic(current_user_info.smb_name, current_user_info.domain,
				   desthost, sizeof(desthost));
		strupper_m(desthost);

		if(!resolve_name( desthost, &dest_ip, 0x20)) {
			DEBUG(1,("server_cryptkey: Can't resolve address for %s\n",desthost));
			continue;
		}

		if (ismyip(dest_ip)) {
			DEBUG(1,("Password server loop - disabling password server %s\n",desthost));
			continue;
		}

		/* we use a mutex to prevent two connections at once - when a 
		   Win2k PDC get two connections where one hasn't completed a 
		   session setup yet it will send a TCP reset to the first 
		   connection (tridge) */

		if (!grab_server_mutex(desthost)) {
			return NULL;
		}

		if (cli_connect(cli, desthost, &dest_ip)) {
			DEBUG(3,("connected to password server %s\n",desthost));
			connected_ok = True;
			break;
		}
	}

	if (!connected_ok) {
		release_server_mutex();
		DEBUG(0,("password server not available\n"));
		cli_shutdown(cli);
		return NULL;
	}
	
	if (!attempt_netbios_session_request(&cli, global_myname(), 
					     desthost, &dest_ip)) {
		release_server_mutex();
		DEBUG(1,("password server fails session request\n"));
		cli_shutdown(cli);
		return NULL;
	}
	
	if (strequal(desthost,myhostname())) {
		exit_server_cleanly("Password server loop!");
	}
	
	DEBUG(3,("got session\n"));

	if (!cli_negprot(cli)) {
		DEBUG(1,("%s rejected the negprot\n",desthost));
		release_server_mutex();
		cli_shutdown(cli);
		return NULL;
	}

	if (cli->protocol < PROTOCOL_LANMAN2 ||
	    !(cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) {
		DEBUG(1,("%s isn't in user level security mode\n",desthost));
		release_server_mutex();
		cli_shutdown(cli);
		return NULL;
	}

	/* Get the first session setup done quickly, to avoid silly 
	   Win2k bugs.  (The next connection to the server will kill
	   this one... 
	*/

	if (!NT_STATUS_IS_OK(cli_session_setup(cli, "", "", 0, "", 0,
					       ""))) {
		DEBUG(0,("%s rejected the initial session setup (%s)\n",
			 desthost, cli_errstr(cli)));
		release_server_mutex();
		cli_shutdown(cli);
		return NULL;
	}
	
	release_server_mutex();

	DEBUG(3,("password server OK\n"));
	
	return cli;
}
Example #17
0
static struct cli_state 
*smb_complete_connection(const char *myname,
            const char *server,
            int port,
            const char *username, 
            const char *password, 
            const char *workgroup, 
            const char *share,
            int flags)
{
  struct cli_state  *cli;    /* New connection */    
  NTSTATUS nt_status;
  
  /* Start the SMB connection */
  nt_status = cli_start_connection( &cli, myname, server, NULL, port, 
                                    Undefined, flags, NULL);
  if (!NT_STATUS_IS_OK(nt_status)) 
  {
    return NULL;      
  }
    
  /* We pretty much guarentee password must be valid or a pointer
     to a 0 char. */
  if (!password) {
    return NULL;
  }
  
  if ( (username) && (*username) && 
      (strlen(password) == 0 ) && 
       (cli->use_kerberos) ) 
  {
    /* Use kerberos authentication */
    struct passwd *pw;
    char *cache_file;
    
    
    if ( !(pw = sys_getpwnam(username)) ) {
      fprintf(stderr,"ERROR Can not get %s uid\n", username);
      cli_shutdown(cli);
      return NULL;
    }

    /*
     * Get the ticket cache of the user to set KRB5CCNAME env
     * variable
     */
    cache_file = get_ticket_cache( pw->pw_uid );
    if ( cache_file == NULL ) 
    {
      fprintf(stderr, "ERROR: Can not get the ticket cache for %s\n", username);
      cli_shutdown(cli);
      return NULL;
    }

    if ( setenv(KRB5CCNAME, cache_file, OVERWRITE) < 0 ) 
    {
      fprintf(stderr, "ERROR: Can not add KRB5CCNAME to the environment");
      cli_shutdown(cli);
      free(cache_file);
      return NULL;
    }
    free(cache_file);

    /*
     * Change the UID of the process to be able to read the kerberos
     * ticket cache
     */
    setuid(pw->pw_uid);

  }
   
   
  if (!NT_STATUS_IS_OK(cli_session_setup(cli, username,
					 password, strlen(password)+1, 
					 password, strlen(password)+1,
					 workgroup)))
  {
    fprintf(stderr,"ERROR: Session setup failed: %s\n", cli_errstr(cli));
    if (NT_STATUS_V(cli_nt_error(cli)) == 
        NT_STATUS_V(NT_STATUS_MORE_PROCESSING_REQUIRED))
    {
      fprintf(stderr, "did you forget to run kinit?\n");
    }
    cli_shutdown(cli);

    return NULL;
  }
    
  if (!cli_send_tconX(cli, share, "?????", password, strlen(password)+1)) 
  {
    fprintf(stderr, "ERROR: Tree connect failed (%s)\n", cli_errstr(cli));
    cli_shutdown(cli);
    return NULL;
  }
    
  return cli;
}
Example #18
0
int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, 
		 void (*fn)(const char *, file_info *, const char *, void *), void *state)
{
	char *p;
	int received = 0;
	BOOL first = True;
	char status[21];
	int num_asked = (cli->max_xmit - 100)/DIR_STRUCT_SIZE;
	int num_received = 0;
	int i;
	char *dirlist = NULL;
	pstring mask;
	
	ZERO_ARRAY(status);

	pstrcpy(mask,Mask);
  
	while (1) {
		memset(cli->outbuf,'\0',smb_size);
		memset(cli->inbuf,'\0',smb_size);

		set_message(cli->outbuf,2,0,True);

		SCVAL(cli->outbuf,smb_com,SMBsearch);

		SSVAL(cli->outbuf,smb_tid,cli->cnum);
		cli_setup_packet(cli);

		SSVAL(cli->outbuf,smb_vwv0,num_asked);
		SSVAL(cli->outbuf,smb_vwv1,attribute);
  
		p = smb_buf(cli->outbuf);
		*p++ = 4;
      
		p += clistr_push(cli, p, first?mask:"", -1, STR_TERMINATE);
		*p++ = 5;
		if (first) {
			SSVAL(p,0,0);
			p += 2;
		} else {
			SSVAL(p,0,21);
			p += 2;
			memcpy(p,status,21);
			p += 21;
		}

		cli_setup_bcc(cli, p);
		cli_send_smb(cli);
		if (!cli_receive_smb(cli)) break;

		received = SVAL(cli->inbuf,smb_vwv0);
		if (received <= 0) break;

		first = False;

		dirlist = (char *)SMB_REALLOC(
			dirlist,(num_received + received)*DIR_STRUCT_SIZE);
		if (!dirlist) {
			DEBUG(0,("cli_list_old: failed to expand dirlist"));
			return 0;
		}

		p = smb_buf(cli->inbuf) + 3;

		memcpy(dirlist+num_received*DIR_STRUCT_SIZE,
		       p,received*DIR_STRUCT_SIZE);
		
		memcpy(status,p + ((received-1)*DIR_STRUCT_SIZE),21);
		
		num_received += received;
		
		if (cli_is_error(cli)) break;
	}

	if (!first) {
		memset(cli->outbuf,'\0',smb_size);
		memset(cli->inbuf,'\0',smb_size);

		set_message(cli->outbuf,2,0,True);
		SCVAL(cli->outbuf,smb_com,SMBfclose);
		SSVAL(cli->outbuf,smb_tid,cli->cnum);
		cli_setup_packet(cli);

		SSVAL(cli->outbuf, smb_vwv0, 0); /* find count? */
		SSVAL(cli->outbuf, smb_vwv1, attribute);

		p = smb_buf(cli->outbuf);
		*p++ = 4;
		fstrcpy(p, "");
		p += strlen(p) + 1;
		*p++ = 5;
		SSVAL(p, 0, 21);
		p += 2;
		memcpy(p,status,21);
		p += 21;
		
		cli_setup_bcc(cli, p);
		cli_send_smb(cli);
		if (!cli_receive_smb(cli)) {
			DEBUG(0,("Error closing search: %s\n",cli_errstr(cli)));
		}
	}

	for (p=dirlist,i=0;i<num_received;i++) {
		file_info finfo;
		p += interpret_short_filename(cli, p,&finfo);
		fn("\\", &finfo, Mask, state);
	}

	SAFE_FREE(dirlist);
	return(num_received);
}
Example #19
0
static struct cli_state *do_connect( const char *server, const char *share,
                                     BOOL show_sessetup )
{
	struct cli_state *c = NULL;
	struct nmb_name called, calling;
	const char *server_n;
	struct in_addr ip;
	pstring servicename;
	char *sharename;
	fstring newserver, newshare;
	NTSTATUS status;
	
	/* make a copy so we don't modify the global string 'service' */
	pstrcpy(servicename, share);
	sharename = servicename;
	if (*sharename == '\\') {
		server = sharename+2;
		sharename = strchr_m(server,'\\');
		if (!sharename) return NULL;
		*sharename = 0;
		sharename++;
	}

	server_n = server;
	
	zero_ip(&ip);

	make_nmb_name(&calling, global_myname(), 0x0);
	make_nmb_name(&called , server, name_type);

 again:
	zero_ip(&ip);
	if (have_ip) 
		ip = dest_ip;

	/* have to open a new connection */
	if (!(c=cli_initialise()) || (cli_set_port(c, port) != port)) {
		d_printf("Connection to %s failed\n", server_n);
		return NULL;
	}
	status = cli_connect(c, server_n, &ip);
	if (!NT_STATUS_IS_OK(status)) {
		d_printf("Connection to %s failed (Error %s)\n", server_n, nt_errstr(status));
		return NULL;
	}

	c->protocol = max_protocol;
	c->use_kerberos = use_kerberos;
	cli_setup_signing_state(c, signing_state);
		

	if (!cli_session_request(c, &calling, &called, NULL)) {
		char *p;
		d_printf("session request to %s failed (%s)\n", 
			 called.name, cli_errstr(c));
		cli_shutdown(c);
		c = NULL;
		if ((p=strchr_m(called.name, '.'))) {
			*p = 0;
			goto again;
		}
		if (strcmp(called.name, "*SMBSERVER")) {
			make_nmb_name(&called , "*SMBSERVER", 0x20);
			goto again;
		}
		return NULL;
	}

	DEBUG(4,(" session request ok\n"));

	if (!cli_negprot(c)) {
		d_printf("protocol negotiation failed\n");
		cli_shutdown(c);
		return NULL;
	}

	if (!got_pass) {
		char *pass = getpass("Password: "******"", "", 0, "", 0,
						       lp_workgroup()))) { 
			d_printf("session setup failed: %s\n", cli_errstr(c));
			if (NT_STATUS_V(cli_nt_error(c)) == 
			    NT_STATUS_V(NT_STATUS_MORE_PROCESSING_REQUIRED))
				d_printf("did you forget to run kinit?\n");
			cli_shutdown(c);
			return NULL;
		}
		d_printf("Anonymous login successful\n");
	}

	if ( show_sessetup ) {
		if (*c->server_domain) {
			DEBUG(0,("Domain=[%s] OS=[%s] Server=[%s]\n",
				c->server_domain,c->server_os,c->server_type));
		} else if (*c->server_os || *c->server_type){
			DEBUG(0,("OS=[%s] Server=[%s]\n",
				 c->server_os,c->server_type));
		}		
	}
	DEBUG(4,(" session setup ok\n"));

	/* here's the fun part....to support 'msdfs proxy' shares
	   (on Samba or windows) we have to issues a TRANS_GET_DFS_REFERRAL 
	   here before trying to connect to the original share.
	   check_dfs_proxy() will fail if it is a normal share. */

	if ( (c->capabilities & CAP_DFS) && cli_check_msdfs_proxy( c, sharename, newserver, newshare ) ) {
		cli_shutdown(c);
		return do_connect( newserver, newshare, False );
	}

	/* must be a normal share */

	if (!cli_send_tconX(c, sharename, "?????", password, strlen(password)+1)) {
		d_printf("tree connect failed: %s\n", cli_errstr(c));
		cli_shutdown(c);
		return NULL;
	}

	DEBUG(4,(" tconx ok\n"));

	return c;
}
Example #20
0
static int parse_quota_set(pstring set_str, pstring username_str, enum SMB_QUOTA_TYPE *qtype, int *cmd, SMB_NTQUOTA_STRUCT *pqt)
{
	char *p = set_str,*p2;
	int todo;
	BOOL stop = False;
	BOOL enable = False;
	BOOL deny = False;
	
	if (strnequal(set_str,"UQLIM:",6)) {
		p += 6;
		*qtype = SMB_USER_QUOTA_TYPE;
		*cmd = QUOTA_SETLIM;
		todo = PARSE_LIM;
		if ((p2=strstr(p,":"))==NULL) {
			return -1;
		}
		
		*p2 = '\0';
		p2++;
		
		fstrcpy(username_str,p);
		p = p2;
	} else if (strnequal(set_str,"FSQLIM:",7)) {
		p +=7;
		*qtype = SMB_USER_FS_QUOTA_TYPE;
		*cmd = QUOTA_SETLIM;
		todo = PARSE_LIM;
	} else if (strnequal(set_str,"FSQFLAGS:",9)) {
		p +=9;
		todo = PARSE_FLAGS;
		*qtype = SMB_USER_FS_QUOTA_TYPE;
		*cmd = QUOTA_SETFLAGS;
	} else {
		return -1;
	}

	switch (todo) {
		case PARSE_LIM:
#if defined(HAVE_LONGLONG)
			if (sscanf(p,"%llu/%llu",&pqt->softlim,&pqt->hardlim)!=2) {
#else
			if (sscanf(p,"%lu/%lu",&pqt->softlim,&pqt->hardlim)!=2) {
#endif
				return -1;
			}
			
			break;
		case PARSE_FLAGS:
			while (!stop) {

				if ((p2=strstr(p,"/"))==NULL) {
					stop = True;
				} else {
					*p2 = '\0';
					p2++;
				}

				if (strnequal(p,"QUOTA_ENABLED",13)) {
					enable = True;
				} else if (strnequal(p,"DENY_DISK",9)) {
					deny = True;
				} else if (strnequal(p,"LOG_SOFTLIMIT",13)) {
					pqt->qflags |= QUOTAS_LOG_THRESHOLD;
				} else if (strnequal(p,"LOG_HARDLIMIT",13)) {
					pqt->qflags |= QUOTAS_LOG_LIMIT;
				} else {
					return -1;
				}

				p=p2;
			}

			if (deny) {
				pqt->qflags |= QUOTAS_DENY_DISK;
			} else if (enable) {
				pqt->qflags |= QUOTAS_ENABLED;
			}
			
			break;	
	}

	return 0;
}

static int do_quota(struct cli_state *cli, enum SMB_QUOTA_TYPE qtype, uint16 cmd, pstring username_str, SMB_NTQUOTA_STRUCT *pqt)
{
	uint32 fs_attrs = 0;
	int quota_fnum = 0;
	SMB_NTQUOTA_LIST *qtl = NULL;
	SMB_NTQUOTA_STRUCT qt;
	ZERO_STRUCT(qt);

	if (!cli_get_fs_attr_info(cli, &fs_attrs)) {
		d_printf("Failed to get the filesystem attributes %s.\n",
			cli_errstr(cli));
		return -1;
	}

	if (!(fs_attrs & FILE_VOLUME_QUOTAS)) {
		d_printf("Quotas are not supported by the server.\n");
		return 0;	
	}

	if (!cli_get_quota_handle(cli, &quota_fnum)) {
		d_printf("Failed to open \\%s  %s.\n",
			FAKE_FILE_NAME_QUOTA,cli_errstr(cli));
		return -1;
	}

	switch(qtype) {
		case SMB_USER_QUOTA_TYPE:
			if (!StringToSid(&qt.sid, username_str)) {
				d_printf("StringToSid() failed for [%s]\n",username_str);
				return -1;
			}
			
			switch(cmd) {
				case QUOTA_GET:
					if (!cli_get_user_quota(cli, quota_fnum, &qt)) {
						d_printf("%s cli_get_user_quota %s\n",
							 cli_errstr(cli),username_str);
						return -1;
					}
					dump_ntquota(&qt,verbose,numeric,SidToString);
					break;
				case QUOTA_SETLIM:
					pqt->sid = qt.sid;
					if (!cli_set_user_quota(cli, quota_fnum, pqt)) {
						d_printf("%s cli_set_user_quota %s\n",
							 cli_errstr(cli),username_str);
						return -1;
					}
					if (!cli_get_user_quota(cli, quota_fnum, &qt)) {
						d_printf("%s cli_get_user_quota %s\n",
							 cli_errstr(cli),username_str);
						return -1;
					}
					dump_ntquota(&qt,verbose,numeric,SidToString);
					break;
				case QUOTA_LIST:
					if (!cli_list_user_quota(cli, quota_fnum, &qtl)) {
						d_printf("%s cli_set_user_quota %s\n",
							 cli_errstr(cli),username_str);
						return -1;
					}
					dump_ntquota_list(&qtl,verbose,numeric,SidToString);
					free_ntquota_list(&qtl);					
					break;
				default:
					d_printf("Unknown Error\n");
					return -1;
			} 
			break;
		case SMB_USER_FS_QUOTA_TYPE:
			switch(cmd) {
				case QUOTA_GET:
					if (!cli_get_fs_quota_info(cli, quota_fnum, &qt)) {
						d_printf("%s cli_get_fs_quota_info\n",
							 cli_errstr(cli));
						return -1;
					}
					dump_ntquota(&qt,True,numeric,NULL);
					break;
				case QUOTA_SETLIM:
					if (!cli_get_fs_quota_info(cli, quota_fnum, &qt)) {
						d_printf("%s cli_get_fs_quota_info\n",
							 cli_errstr(cli));
						return -1;
					}
					qt.softlim = pqt->softlim;
					qt.hardlim = pqt->hardlim;
					if (!cli_set_fs_quota_info(cli, quota_fnum, &qt)) {
						d_printf("%s cli_set_fs_quota_info\n",
							 cli_errstr(cli));
						return -1;
					}
					if (!cli_get_fs_quota_info(cli, quota_fnum, &qt)) {
						d_printf("%s cli_get_fs_quota_info\n",
							 cli_errstr(cli));
						return -1;
					}
					dump_ntquota(&qt,True,numeric,NULL);
					break;
				case QUOTA_SETFLAGS:
					if (!cli_get_fs_quota_info(cli, quota_fnum, &qt)) {
						d_printf("%s cli_get_fs_quota_info\n",
							 cli_errstr(cli));
						return -1;
					}
					qt.qflags = pqt->qflags;
					if (!cli_set_fs_quota_info(cli, quota_fnum, &qt)) {
						d_printf("%s cli_set_fs_quota_info\n",
							 cli_errstr(cli));
						return -1;
					}
					if (!cli_get_fs_quota_info(cli, quota_fnum, &qt)) {
						d_printf("%s cli_get_fs_quota_info\n",
							 cli_errstr(cli));
						return -1;
					}
					dump_ntquota(&qt,True,numeric,NULL);
					break;
				default:
					d_printf("Unknown Error\n");
					return -1;
			} 		
			break;
		default:
			d_printf("Unknown Error\n");
			return -1;
	}

	cli_close(cli, quota_fnum);

	return 0;
}
Example #21
0
static SMBCSRV *
SMBC_server_internal(TALLOC_CTX *ctx,
            SMBCCTX *context,
            bool connect_if_not_found,
            const char *server,
            const char *share,
            char **pp_workgroup,
            char **pp_username,
            char **pp_password,
	    bool *in_cache)
{
	SMBCSRV *srv=NULL;
	char *workgroup = NULL;
	struct cli_state *c;
	struct nmb_name called, calling;
	const char *server_n = server;
	struct sockaddr_storage ss;
	int tried_reverse = 0;
        int port_try_first;
        int port_try_next;
        int is_ipc = (share != NULL && strcmp(share, "IPC$") == 0);
	uint32 fs_attrs = 0;
        const char *username_used;
 	NTSTATUS status;
	char *newserver, *newshare;
	
	zero_sockaddr(&ss);
	ZERO_STRUCT(c);
	*in_cache = false;

	if (server[0] == 0) {
		errno = EPERM;
		return NULL;
	}
	
        /* Look for a cached connection */
        srv = SMBC_find_server(ctx, context, server, share,
                               pp_workgroup, pp_username, pp_password);

        /*
         * If we found a connection and we're only allowed one share per
         * server...
         */
        if (srv &&
            *share != '\0' &&
            smbc_getOptionOneSharePerServer(context)) {
			
                /*
                 * ... then if there's no current connection to the share,
                 * connect to it.  SMBC_find_server(), or rather the function
                 * pointed to by context->get_cached_srv_fn which
                 * was called by SMBC_find_server(), will have issued a tree
                 * disconnect if the requested share is not the same as the
                 * one that was already connected.
                 */

		/*
		 * Use srv->cli->desthost and srv->cli->share instead of
		 * server and share below to connect to the actual share,
		 * i.e., a normal share or a referred share from
		 * 'msdfs proxy' share.
		 */
                if (srv->cli->cnum == (uint16) -1) {
                        /* Ensure we have accurate auth info */
			SMBC_call_auth_fn(ctx, context,
					  srv->cli->desthost,
					  srv->cli->share,
                                          pp_workgroup,
                                          pp_username,
                                          pp_password);

			if (!*pp_workgroup || !*pp_username || !*pp_password) {
				errno = ENOMEM;
				cli_shutdown(srv->cli);
				srv->cli = NULL;
				smbc_getFunctionRemoveCachedServer(context)(context,
                                                                            srv);
				return NULL;
			}

			/*
			 * We don't need to renegotiate encryption
			 * here as the encryption context is not per
			 * tid.
			 */

			status = cli_tcon_andx(srv->cli, srv->cli->share, "?????",
					       *pp_password,
					       strlen(*pp_password)+1);
			if (!NT_STATUS_IS_OK(status)) {
                                errno = map_errno_from_nt_status(status);
                                cli_shutdown(srv->cli);
				srv->cli = NULL;
                                smbc_getFunctionRemoveCachedServer(context)(context,
                                                                            srv);
                                srv = NULL;
                        }

                        /* Determine if this share supports case sensitivity */
                        if (is_ipc) {
                                DEBUG(4,
                                      ("IPC$ so ignore case sensitivity\n"));
                        } else if (!cli_get_fs_attr_info(c, &fs_attrs)) {
                                DEBUG(4, ("Could not retrieve "
                                          "case sensitivity flag: %s.\n",
                                          cli_errstr(c)));

                                /*
                                 * We can't determine the case sensitivity of
                                 * the share. We have no choice but to use the
                                 * user-specified case sensitivity setting.
                                 */
                                if (smbc_getOptionCaseSensitive(context)) {
                                        cli_set_case_sensitive(c, True);
                                } else {
                                        cli_set_case_sensitive(c, False);
                                }
                        } else {
                                DEBUG(4,
                                      ("Case sensitive: %s\n",
                                       (fs_attrs & FILE_CASE_SENSITIVE_SEARCH
                                        ? "True"
                                        : "False")));
                                cli_set_case_sensitive(
                                        c,
                                        (fs_attrs & FILE_CASE_SENSITIVE_SEARCH
                                         ? True
                                         : False));
                        }

                        /*
                         * Regenerate the dev value since it's based on both
                         * server and share
                         */
                        if (srv) {
                                srv->dev = (dev_t)(str_checksum(srv->cli->desthost) ^
                                                   str_checksum(srv->cli->share));
                        }
                }
        }
	
        /* If we have a connection... */
        if (srv) {
                /* ... then we're done here.  Give 'em what they came for. */
		*in_cache = true;
                goto done;
        }

        /* If we're not asked to connect when a connection doesn't exist... */
        if (! connect_if_not_found) {
                /* ... then we're done here. */
                return NULL;
        }

	if (!*pp_workgroup || !*pp_username || !*pp_password) {
		errno = ENOMEM;
		return NULL;
	}

	make_nmb_name(&calling, smbc_getNetbiosName(context), 0x0);
	make_nmb_name(&called , server, 0x20);

	DEBUG(4,("SMBC_server: server_n=[%s] server=[%s]\n", server_n, server));

	DEBUG(4,(" -> server_n=[%s] server=[%s]\n", server_n, server));

again:

	zero_sockaddr(&ss);

	/* have to open a new connection */
	if ((c = cli_initialise()) == NULL) {
		errno = ENOMEM;
		return NULL;
	}

        if (smbc_getOptionUseKerberos(context)) {
		c->use_kerberos = True;
	}

        if (smbc_getOptionFallbackAfterKerberos(context)) {
		c->fallback_after_kerberos = True;
	}

        if (smbc_getOptionUseCCache(context)) {
		c->use_ccache = True;
	}

	c->timeout = smbc_getTimeout(context);

        /*
         * Force use of port 139 for first try if share is $IPC, empty, or
         * null, so browse lists can work
         */
       if (share == NULL || *share == '\0' || is_ipc) {
                port_try_first = 139;
                port_try_next = 445;
       } else {
                port_try_first = 445;
                port_try_next = 139;
       }

	c->port = port_try_first;
	
	status = cli_connect(c, server_n, &ss);
	if (!NT_STATUS_IS_OK(status)) {

                /* First connection attempt failed.  Try alternate port. */
                c->port = port_try_next;

                status = cli_connect(c, server_n, &ss);
		if (!NT_STATUS_IS_OK(status)) {
			cli_shutdown(c);
			errno = ETIMEDOUT;
			return NULL;
		}
	}
	
	if (!cli_session_request(c, &calling, &called)) {
		cli_shutdown(c);
		if (strcmp(called.name, "*SMBSERVER")) {
			make_nmb_name(&called , "*SMBSERVER", 0x20);
			goto again;
		} else {  /* Try one more time, but ensure we don't loop */

			/* Only try this if server is an IP address ... */

			if (is_ipaddress(server) && !tried_reverse) {
				fstring remote_name;
				struct sockaddr_storage rem_ss;

				if (!interpret_string_addr(&rem_ss, server,
                                                           NI_NUMERICHOST)) {
					DEBUG(4, ("Could not convert IP address "
                                                  "%s to struct sockaddr_storage\n",
                                                  server));
					errno = ETIMEDOUT;
					return NULL;
				}

				tried_reverse++; /* Yuck */

				if (name_status_find("*", 0, 0,
                                                     &rem_ss, remote_name)) {
					make_nmb_name(&called,
                                                      remote_name,
                                                      0x20);
					goto again;
				}
			}
		}
		errno = ETIMEDOUT;
		return NULL;
	}

	DEBUG(4,(" session request ok\n"));
	

	status = cli_negprot(c);

	if (!NT_STATUS_IS_OK(status)) {
		cli_shutdown(c);
		errno = ETIMEDOUT;
		return NULL;
	}

        username_used = *pp_username;

	if (!NT_STATUS_IS_OK(cli_session_setup(c, username_used,
					       *pp_password,
                                               strlen(*pp_password),
					       *pp_password,
                                               strlen(*pp_password),
					       *pp_workgroup))) {
fprintf(stderr, "JerryLin: Libsmb_server.c->SMBC_server_internal: cli_session_setup fail with username=[%s], password=[%s]\n", username_used, *pp_password);
                /* Failed.  Try an anonymous login, if allowed by flags. */
                username_used = "";

                if (smbc_getOptionNoAutoAnonymousLogin(context) ||
                    !NT_STATUS_IS_OK(cli_session_setup(c, username_used,
                                                       *pp_password, 1,
                                                       *pp_password, 0,
                                                       *pp_workgroup))) {

                        cli_shutdown(c);
                        errno = EPERM;
                        return NULL;
                }
	}
	
	status = cli_init_creds(c, username_used,
				*pp_workgroup, *pp_password);
	if (!NT_STATUS_IS_OK(status)) {
		errno = map_errno_from_nt_status(status);
		cli_shutdown(c);
		return NULL;
	}

	DEBUG(4,(" session setup ok\n"));
	
	/* here's the fun part....to support 'msdfs proxy' shares
	   (on Samba or windows) we have to issues a TRANS_GET_DFS_REFERRAL
	   here before trying to connect to the original share.
	   cli_check_msdfs_proxy() will fail if it is a normal share. */

	if ((c->capabilities & CAP_DFS) &&
			cli_check_msdfs_proxy(ctx, c, share,
				&newserver, &newshare,
				/* FIXME: cli_check_msdfs_proxy() does
				   not support smbc_smb_encrypt_level type */
				context->internal->smb_encryption_level ?
					true : false,
				*pp_username,
				*pp_password,
				*pp_workgroup)) {
		cli_shutdown(c);
		srv = SMBC_server_internal(ctx, context, connect_if_not_found,
				newserver, newshare, pp_workgroup,
				pp_username, pp_password, in_cache);
		TALLOC_FREE(newserver);
		TALLOC_FREE(newshare);
		return srv;
	}
	
	/* must be a normal share */
	status = cli_tcon_andx(c, share, "?????", *pp_password,
			       strlen(*pp_password)+1);
	if (!NT_STATUS_IS_OK(status)) {
		errno = map_errno_from_nt_status(status);
		fprintf(stderr, "JerryLin: Libsmb_server.c->SMBC_server_internal: cli_tcon_andx return %08X, errno=[%d]\n", NT_STATUS_V(status), errno);
		cli_shutdown(c);
		return NULL;
	}
	
	DEBUG(4,(" tconx ok\n"));

        /* Determine if this share supports case sensitivity */
	if (is_ipc) {
                DEBUG(4, ("IPC$ so ignore case sensitivity\n"));
        } else if (!cli_get_fs_attr_info(c, &fs_attrs)) {
                DEBUG(4, ("Could not retrieve case sensitivity flag: %s.\n",
                          cli_errstr(c)));

                /*
                 * We can't determine the case sensitivity of the share. We
                 * have no choice but to use the user-specified case
                 * sensitivity setting.
                 */
                if (smbc_getOptionCaseSensitive(context)) {
                        cli_set_case_sensitive(c, True);
                } else {
                        cli_set_case_sensitive(c, False);
                }
	} else {
                DEBUG(4, ("Case sensitive: %s\n",
                          (fs_attrs & FILE_CASE_SENSITIVE_SEARCH
                           ? "True"
                           : "False")));
                cli_set_case_sensitive(c,
                                       (fs_attrs & FILE_CASE_SENSITIVE_SEARCH
                                        ? True
                                        : False));
        }
	

	if (context->internal->smb_encryption_level) {
		/* Attempt UNIX smb encryption. */
		if (!NT_STATUS_IS_OK(cli_force_encryption(c,
                                                          username_used,
                                                          *pp_password,
                                                          *pp_workgroup))) {

			/*
			 * context->smb_encryption_level == 1
			 * means don't fail if encryption can't be negotiated,
			 * == 2 means fail if encryption can't be negotiated.
			 */

			DEBUG(4,(" SMB encrypt failed\n"));

			if (context->internal->smb_encryption_level == 2) {
	                        cli_shutdown(c);
				errno = EPERM;
				return NULL;
			}
		}
		DEBUG(4,(" SMB encrypt ok\n"));
	}

	/*
	 * Ok, we have got a nice connection
	 * Let's allocate a server structure.
	 */

	srv = SMB_MALLOC_P(SMBCSRV);
	if (!srv) {
		cli_shutdown(c);
		errno = ENOMEM;
		return NULL;
	}

	ZERO_STRUCTP(srv);
	srv->cli = c;
	srv->dev = (dev_t)(str_checksum(server) ^ str_checksum(share));
        srv->no_pathinfo = False;
        srv->no_pathinfo2 = False;
        srv->no_nt_session = False;

done:
	if (!pp_workgroup || !*pp_workgroup || !**pp_workgroup) {
		workgroup = talloc_strdup(ctx, smbc_getWorkgroup(context));
	} else {
		workgroup = *pp_workgroup;
	}
	if(!workgroup) {
		return NULL;
	}

	/* set the credentials to make DFS work */
	smbc_set_credentials_with_fallback(context,
					   workgroup,
				    	   *pp_username,
				   	   *pp_password);

	return srv;
}
Example #22
0
NTSTATUS cli_full_connection(struct cli_state **output_cli, 
			     const char *my_name, const char *dest_host, 
			     struct in_addr *dest_ip, int port,
			     const char *service, const char *service_type,
			     const char *user, const char *domain, 
			     const char *password, int pass_len) 
{
	struct ntuser_creds creds;
	NTSTATUS nt_status;
	struct nmb_name calling;
	struct nmb_name called;
	struct cli_state *cli;
	struct in_addr ip;
	
	if (!output_cli)
		DEBUG(0, ("output_cli is NULL!?!"));

	*output_cli = NULL;
	
	make_nmb_name(&calling, my_name, 0x0);
	make_nmb_name(&called , dest_host, 0x20);

again:

	if (!(cli = cli_initialise(NULL)))
		return NT_STATUS_NO_MEMORY;
	
	if (cli_set_port(cli, port) != port) {
		cli_shutdown(cli);
		return NT_STATUS_UNSUCCESSFUL;
	}

	ip = *dest_ip;
	
	DEBUG(3,("Connecting to host=%s share=%s\n", dest_host, service));
	
	if (!cli_connect(cli, dest_host, &ip)) {
		DEBUG(1,("cli_establish_connection: failed to connect to %s (%s)\n",
			 nmb_namestr(&called), inet_ntoa(*dest_ip)));
		cli_shutdown(cli);
		return NT_STATUS_UNSUCCESSFUL;
	}

	if (!cli_session_request(cli, &calling, &called)) {
		char *p;
		DEBUG(1,("session request to %s failed (%s)\n", 
			 called.name, cli_errstr(cli)));
		cli_shutdown(cli);
		if ((p=strchr(called.name, '.')) && !is_ipaddress(called.name)) {
			*p = 0;
			goto again;
		}
		if (strcmp(called.name, "*SMBSERVER")) {
			make_nmb_name(&called , "*SMBSERVER", 0x20);
			goto again;
		}
		return NT_STATUS_UNSUCCESSFUL;
	}

	if (!cli_negprot(cli)) {
		DEBUG(1,("failed negprot\n"));
		nt_status = NT_STATUS_UNSUCCESSFUL;
		cli_shutdown(cli);
		return nt_status;
	}

	if (!cli_session_setup(cli, user, password, pass_len, password, pass_len, 
			       domain)) {
		DEBUG(1,("failed session setup\n"));
		nt_status = cli_nt_error(cli);
		cli_shutdown(cli);
		if (NT_STATUS_IS_OK(nt_status)) 
			nt_status = NT_STATUS_UNSUCCESSFUL;
		return nt_status;
	} 

	if (service) {
		if (!cli_send_tconX(cli, service, service_type,
				    password, pass_len)) {
			DEBUG(1,("failed tcon_X\n"));
			nt_status = cli_nt_error(cli);
			cli_shutdown(cli);
			if (NT_STATUS_IS_OK(nt_status)) 
				nt_status = NT_STATUS_UNSUCCESSFUL;
			return nt_status;
		}
	}

	init_creds(&creds, user, domain, password, pass_len);
	cli_init_creds(cli, &creds);

	*output_cli = cli;
	return NT_STATUS_OK;
}
Example #23
0
NTSTATUS remote_password_change(const char *remote_machine, const char *user_name, 
				const char *old_passwd, const char *new_passwd,
				char **err_str)
{
	struct nmb_name calling, called;
	struct cli_state *cli;
	struct rpc_pipe_client *pipe_hnd;
	struct sockaddr_storage ss;

	NTSTATUS result;
	bool pass_must_change = False;

	*err_str = NULL;

	if(!resolve_name( remote_machine, &ss, 0x20)) {
		asprintf(err_str, "Unable to find an IP address for machine "
			 "%s.\n", remote_machine);
		return NT_STATUS_UNSUCCESSFUL;
	}
 
	cli = cli_initialise();
	if (!cli) {
		return NT_STATUS_NO_MEMORY;
	}

	result = cli_connect(cli, remote_machine, &ss);
	if (!NT_STATUS_IS_OK(result)) {
		asprintf(err_str, "Unable to connect to SMB server on "
			 "machine %s. Error was : %s.\n",
			 remote_machine, nt_errstr(result));
		cli_shutdown(cli);
		return result;
	}
  
	make_nmb_name(&calling, global_myname() , 0x0);
	make_nmb_name(&called , remote_machine, 0x20);
	
	if (!cli_session_request(cli, &calling, &called)) {
		asprintf(err_str, "machine %s rejected the session setup. "
			 "Error was : %s.\n",
			 remote_machine, cli_errstr(cli) );
		result = cli_nt_error(cli);
		cli_shutdown(cli);
		return result;
	}
  
	cli->protocol = PROTOCOL_NT1;

	if (!cli_negprot(cli)) {
		asprintf(err_str, "machine %s rejected the negotiate "
			 "protocol. Error was : %s.\n",        
			 remote_machine, cli_errstr(cli) );
		result = cli_nt_error(cli);
		cli_shutdown(cli);
		return result;
	}
  
	/* Given things like SMB signing, restrict anonymous and the like, 
	   try an authenticated connection first */
	result = cli_session_setup(cli, user_name,
				   old_passwd, strlen(old_passwd)+1,
				   old_passwd, strlen(old_passwd)+1, "");

	if (!NT_STATUS_IS_OK(result)) {

		/* Password must change or Password expired are the only valid
		 * error conditions here from where we can proceed, the rest like
		 * account locked out or logon failure will lead to errors later
		 * anyway */

		if (!NT_STATUS_EQUAL(result, NT_STATUS_PASSWORD_MUST_CHANGE) &&
		    !NT_STATUS_EQUAL(result, NT_STATUS_PASSWORD_EXPIRED)) {
			asprintf(err_str, "Could not connect to machine %s: "
				 "%s\n", remote_machine, cli_errstr(cli));
			cli_shutdown(cli);
			return result;
		}

		pass_must_change = True;

		/*
		 * We should connect as the anonymous user here, in case
		 * the server has "must change password" checked...
		 * Thanks to <*****@*****.**> for this fix.
		 */

		result = cli_session_setup(cli, "", "", 0, "", 0, "");

		if (!NT_STATUS_IS_OK(result)) {
			asprintf(err_str, "machine %s rejected the session "
				 "setup. Error was : %s.\n",        
				 remote_machine, cli_errstr(cli) );
			cli_shutdown(cli);
			return result;
		}

		cli_init_creds(cli, "", "", NULL);
	} else {
		cli_init_creds(cli, user_name, "", old_passwd);
	}

	if (!cli_send_tconX(cli, "IPC$", "IPC", "", 1)) {
		asprintf(err_str, "machine %s rejected the tconX on the IPC$ "
			 "share. Error was : %s.\n",
			 remote_machine, cli_errstr(cli) );
		result = cli_nt_error(cli);
		cli_shutdown(cli);
		return result;
	}

	/* Try not to give the password away too easily */

	if (!pass_must_change) {
		pipe_hnd = cli_rpc_pipe_open_ntlmssp(cli,
						PI_SAMR,
						PIPE_AUTH_LEVEL_PRIVACY,
						"", /* what domain... ? */
						user_name,
						old_passwd,
						&result);
	} else {
		/*
		 * If the user password must be changed the ntlmssp bind will
		 * fail the same way as the session setup above did. The
		 * difference ist that with a pipe bind we don't get a good
		 * error message, the result will be that the rpc call below
		 * will just fail. So we do it anonymously, there's no other
		 * way.
		 */
		pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SAMR, &result);
	}

	if (!pipe_hnd) {
		if (lp_client_lanman_auth()) {
			/* Use the old RAP method. */
			if (!cli_oem_change_password(cli, user_name, new_passwd, old_passwd)) {
				asprintf(err_str, "machine %s rejected the "
					 "password change: Error was : %s.\n",
					 remote_machine, cli_errstr(cli) );
				result = cli_nt_error(cli);
				cli_shutdown(cli);
				return result;
			}
		} else {
			asprintf(err_str, "SAMR connection to machine %s "
				 "failed. Error was %s, but LANMAN password "
				 "changed are disabled\n",
				 nt_errstr(result), remote_machine);
			result = cli_nt_error(cli);
			cli_shutdown(cli);
			return result;
		}
	}

	if (NT_STATUS_IS_OK(result = rpccli_samr_chgpasswd_user(pipe_hnd, pipe_hnd->mem_ctx, user_name, 
							     new_passwd, old_passwd))) {
		/* Great - it all worked! */
		cli_shutdown(cli);
		return NT_STATUS_OK;

	} else if (!(NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED) 
		     || NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL))) {
		/* it failed, but for reasons such as wrong password, too short etc ... */
		
		asprintf(err_str, "machine %s rejected the password change: "
			 "Error was : %s.\n",
			 remote_machine, get_friendly_nt_error_msg(result));
		cli_shutdown(cli);
		return result;
	}

	/* OK, that failed, so try again... */
	cli_rpc_pipe_close(pipe_hnd);
	
	/* Try anonymous NTLMSSP... */
	cli_init_creds(cli, "", "", NULL);
	
	result = NT_STATUS_UNSUCCESSFUL;
	
	/* OK, this is ugly, but... try an anonymous pipe. */
	pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SAMR, &result);

	if ( pipe_hnd &&
		(NT_STATUS_IS_OK(result = rpccli_samr_chgpasswd_user(pipe_hnd,
						pipe_hnd->mem_ctx,
						user_name, 
						new_passwd,
						old_passwd)))) {
		/* Great - it all worked! */
		cli_shutdown(cli);
		return NT_STATUS_OK;
	} else {
		if (!(NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED) 
		      || NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL))) {
			/* it failed, but again it was due to things like new password too short */

			asprintf(err_str, "machine %s rejected the "
				 "(anonymous) password change: Error was : "
				 "%s.\n", remote_machine,
				 get_friendly_nt_error_msg(result));
			cli_shutdown(cli);
			return result;
		}
		
		/* We have failed to change the user's password, and we think the server
		   just might not support SAMR password changes, so fall back */
		
		if (lp_client_lanman_auth()) {
			/* Use the old RAP method. */
			if (cli_oem_change_password(cli, user_name, new_passwd, old_passwd)) {
				/* SAMR failed, but the old LanMan protocol worked! */

				cli_shutdown(cli);
				return NT_STATUS_OK;
			}
			asprintf(err_str, "machine %s rejected the password "
				 "change: Error was : %s.\n",
				 remote_machine, cli_errstr(cli) );
			result = cli_nt_error(cli);
			cli_shutdown(cli);
			return result;
		} else {
			asprintf(err_str, "SAMR connection to machine %s "
				 "failed. Error was %s, but LANMAN password "
				 "changed are disabled\n",
				nt_errstr(result), remote_machine);
			cli_shutdown(cli);
			return NT_STATUS_UNSUCCESSFUL;
		}
	}
}
Example #24
0
static struct cli_state *do_connect( const char *server, const char *share,
                                     BOOL show_sessetup )
{
	struct cli_state *c;
	struct nmb_name called, calling;
	const char *server_n;
	struct in_addr ip;
	pstring servicename;
	char *sharename;
	
	/* make a copy so we don't modify the global string 'service' */
	pstrcpy(servicename, share);
	sharename = servicename;
	if (*sharename == '\\') {
		server = sharename+2;
		sharename = strchr_m(server,'\\');
		if (!sharename) return NULL;
		*sharename = 0;
		sharename++;
	}

	server_n = server;
	
	zero_ip(&ip);

	make_nmb_name(&calling, global_myname(), 0x0);
	make_nmb_name(&called , server, name_type);

 again:
	zero_ip(&ip);
	if (have_ip) 
		ip = dest_ip;

	/* have to open a new connection */
	if (!(c=cli_initialise(NULL)) || (cli_set_port(c, port) != port) ||
	    !cli_connect(c, server_n, &ip)) {
		d_printf("Connection to %s failed\n", server_n);
		return NULL;
	}

	c->protocol = max_protocol;
	c->use_kerberos = use_kerberos;
	cli_setup_signing_state(c, signing_state);
		

	if (!cli_session_request(c, &calling, &called)) {
		char *p;
		d_printf("session request to %s failed (%s)\n", 
			 called.name, cli_errstr(c));
		cli_shutdown(c);
		if ((p=strchr_m(called.name, '.'))) {
			*p = 0;
			goto again;
		}
		if (strcmp(called.name, "*SMBSERVER")) {
			make_nmb_name(&called , "*SMBSERVER", 0x20);
			goto again;
		}
		return NULL;
	}

	DEBUG(4,(" session request ok\n"));

	if (!cli_negprot(c)) {
		d_printf("protocol negotiation failed\n");
		cli_shutdown(c);
		return NULL;
	}

	if (!got_pass) {
		char *pass = getpass("Password: "******"", "", 0, "", 0, lp_workgroup())) { 
			d_printf("session setup failed: %s\n", cli_errstr(c));
			if (NT_STATUS_V(cli_nt_error(c)) == 
			    NT_STATUS_V(NT_STATUS_MORE_PROCESSING_REQUIRED))
				d_printf("did you forget to run kinit?\n");
			cli_shutdown(c);
			return NULL;
		}
		d_printf("Anonymous login successful\n");
	}

	if ( show_sessetup ) {
		if (*c->server_domain) {
			DEBUG(0,("Domain=[%s] OS=[%s] Server=[%s]\n",
				c->server_domain,c->server_os,c->server_type));
		} else if (*c->server_os || *c->server_type){
			DEBUG(0,("OS=[%s] Server=[%s]\n",
				 c->server_os,c->server_type));
		}		
	}
	DEBUG(4,(" session setup ok\n"));

	if (!cli_send_tconX(c, sharename, "?????",
			    password, strlen(password)+1)) {
		d_printf("tree connect failed: %s\n", cli_errstr(c));
		cli_shutdown(c);
		return NULL;
	}

	DEBUG(4,(" tconx ok\n"));

	return c;
}
Example #25
0
static int do_quota(struct cli_state *cli,
		enum SMB_QUOTA_TYPE qtype,
		uint16 cmd,
		const char *username_str,
		SMB_NTQUOTA_STRUCT *pqt)
{
	uint32 fs_attrs = 0;
	int quota_fnum = 0;
	SMB_NTQUOTA_LIST *qtl = NULL;
	SMB_NTQUOTA_STRUCT qt;
	ZERO_STRUCT(qt);

	if (!cli_get_fs_attr_info(cli, &fs_attrs)) {
		d_printf("Failed to get the filesystem attributes %s.\n",
			cli_errstr(cli));
		return -1;
	}

	if (!(fs_attrs & FILE_VOLUME_QUOTAS)) {
		d_printf("Quotas are not supported by the server.\n");
		return 0;
	}

	if (!cli_get_quota_handle(cli, &quota_fnum)) {
		d_printf("Quotas are not enabled on this share.\n");
		d_printf("Failed to open %s  %s.\n",
			FAKE_FILE_NAME_QUOTA_WIN32,cli_errstr(cli));
		return -1;
	}

	switch(qtype) {
		case SMB_USER_QUOTA_TYPE:
			if (!StringToSid(&qt.sid, username_str)) {
				d_printf("StringToSid() failed for [%s]\n",username_str);
				return -1;
			}

			switch(cmd) {
				case QUOTA_GET:
					if (!cli_get_user_quota(cli, quota_fnum, &qt)) {
						d_printf("%s cli_get_user_quota %s\n",
							 cli_errstr(cli),username_str);
						return -1;
					}
					dump_ntquota(&qt,verbose,numeric,SidToString);
					break;
				case QUOTA_SETLIM:
					pqt->sid = qt.sid;
					if (!cli_set_user_quota(cli, quota_fnum, pqt)) {
						d_printf("%s cli_set_user_quota %s\n",
							 cli_errstr(cli),username_str);
						return -1;
					}
					if (!cli_get_user_quota(cli, quota_fnum, &qt)) {
						d_printf("%s cli_get_user_quota %s\n",
							 cli_errstr(cli),username_str);
						return -1;
					}
					dump_ntquota(&qt,verbose,numeric,SidToString);
					break;
				case QUOTA_LIST:
					if (!cli_list_user_quota(cli, quota_fnum, &qtl)) {
						d_printf("%s cli_set_user_quota %s\n",
							 cli_errstr(cli),username_str);
						return -1;
					}
					dump_ntquota_list(&qtl,verbose,numeric,SidToString);
					free_ntquota_list(&qtl);
					break;
				default:
					d_printf("Unknown Error\n");
					return -1;
			}
			break;
		case SMB_USER_FS_QUOTA_TYPE:
			switch(cmd) {
				case QUOTA_GET:
					if (!cli_get_fs_quota_info(cli, quota_fnum, &qt)) {
						d_printf("%s cli_get_fs_quota_info\n",
							 cli_errstr(cli));
						return -1;
					}
					dump_ntquota(&qt,True,numeric,NULL);
					break;
				case QUOTA_SETLIM:
					if (!cli_get_fs_quota_info(cli, quota_fnum, &qt)) {
						d_printf("%s cli_get_fs_quota_info\n",
							 cli_errstr(cli));
						return -1;
					}
					qt.softlim = pqt->softlim;
					qt.hardlim = pqt->hardlim;
					if (!cli_set_fs_quota_info(cli, quota_fnum, &qt)) {
						d_printf("%s cli_set_fs_quota_info\n",
							 cli_errstr(cli));
						return -1;
					}
					if (!cli_get_fs_quota_info(cli, quota_fnum, &qt)) {
						d_printf("%s cli_get_fs_quota_info\n",
							 cli_errstr(cli));
						return -1;
					}
					dump_ntquota(&qt,True,numeric,NULL);
					break;
				case QUOTA_SETFLAGS:
					if (!cli_get_fs_quota_info(cli, quota_fnum, &qt)) {
						d_printf("%s cli_get_fs_quota_info\n",
							 cli_errstr(cli));
						return -1;
					}
					qt.qflags = pqt->qflags;
					if (!cli_set_fs_quota_info(cli, quota_fnum, &qt)) {
						d_printf("%s cli_set_fs_quota_info\n",
							 cli_errstr(cli));
						return -1;
					}
					if (!cli_get_fs_quota_info(cli, quota_fnum, &qt)) {
						d_printf("%s cli_get_fs_quota_info\n",
							 cli_errstr(cli));
						return -1;
					}
					dump_ntquota(&qt,True,numeric,NULL);
					break;
				default:
					d_printf("Unknown Error\n");
					return -1;
			}
			break;
		default:
			d_printf("Unknown Error\n");
			return -1;
	}

	cli_close(cli, quota_fnum);

	return 0;
}
Example #26
0
static void do_atar(char *rname,char *lname,file_info *finfo1)
{
	int fnum;
	SMB_BIG_UINT nread=0;
	char ftype;
	file_info2 finfo;
	BOOL close_done = False;
	BOOL shallitime=True;
	char data[65520];
	int read_size = 65520;
	int datalen=0;

	struct timeval tp_start;

	GetTimeOfDay(&tp_start);

	ftype = '0'; /* An ordinary file ... */

	if (finfo1) {
		finfo.size  = finfo1 -> size;
		finfo.mode  = finfo1 -> mode;
		finfo.uid   = finfo1 -> uid;
		finfo.gid   = finfo1 -> gid;
		finfo.mtime = finfo1 -> mtime;
		finfo.atime = finfo1 -> atime;
		finfo.ctime = finfo1 -> ctime;
		finfo.name  = finfo1 -> name;
	} else {
		finfo.size  = def_finfo.size;
		finfo.mode  = def_finfo.mode;
		finfo.uid   = def_finfo.uid;
		finfo.gid   = def_finfo.gid;
		finfo.mtime = def_finfo.mtime;
		finfo.atime = def_finfo.atime;
		finfo.ctime = def_finfo.ctime;
		finfo.name  = def_finfo.name;
	}

	if (dry_run) {
		DEBUG(3,("skipping file %s of size %12.0f bytes\n", finfo.name,
				(double)finfo.size));
		shallitime=0;
		ttarf+=finfo.size + TBLOCK - (finfo.size % TBLOCK);
		ntarf++;
		return;
	}

	fnum = cli_open(cli, rname, O_RDONLY, DENY_NONE);

	dos_clean_name(rname);

	if (fnum == -1) {
		DEBUG(0,("%s opening remote file %s (%s)\n",
				cli_errstr(cli),rname, cur_dir));
		return;
	}

	finfo.name = string_create_s(strlen(rname));
	if (finfo.name == NULL) {
		DEBUG(0, ("Unable to allocate space for finfo.name in do_atar\n"));
		return;
	}

	safe_strcpy(finfo.name,rname, strlen(rname));
	if (!finfo1) {
		if (!cli_getattrE(cli, fnum, &finfo.mode, &finfo.size, NULL, &finfo.atime, &finfo.mtime)) {
			DEBUG(0, ("getattrE: %s\n", cli_errstr(cli)));
			return;
		}
		finfo.ctime = finfo.mtime;
	}

	DEBUG(3,("file %s attrib 0x%X\n",finfo.name,finfo.mode));

	if (tar_inc && !(finfo.mode & aARCH)) {
		DEBUG(4, ("skipping %s - archive bit not set\n", finfo.name));
		shallitime=0;
	} else if (!tar_system && (finfo.mode & aSYSTEM)) {
		DEBUG(4, ("skipping %s - system bit is set\n", finfo.name));
		shallitime=0;
	} else if (!tar_hidden && (finfo.mode & aHIDDEN)) {
		DEBUG(4, ("skipping %s - hidden bit is set\n", finfo.name));
		shallitime=0;
	} else {
		DEBUG(3,("getting file %s of size %.0f bytes as a tar file %s",
			finfo.name, (double)finfo.size, lname));
      
		/* write a tar header, don't bother with mode - just set to 100644 */
		writetarheader(tarhandle, rname, finfo.size, finfo.mtime, "100644 \0", ftype);

		while (nread < finfo.size && !close_done) {
	      
			DEBUG(3,("nread=%.0f\n",(double)nread));
	      
			datalen = cli_read(cli, fnum, data, nread, read_size);
	      
			if (datalen == -1) {
				DEBUG(0,("Error reading file %s : %s\n", rname, cli_errstr(cli)));
				break;
			}
	      
			nread += datalen;

			/* if file size has increased since we made file size query, truncate
				read so tar header for this file will be correct.
			*/

			if (nread > finfo.size) {
				datalen -= nread - finfo.size;
				DEBUG(0,("File size change - truncating %s to %.0f bytes\n",
							finfo.name, (double)finfo.size));
			}

			/* add received bits of file to buffer - dotarbuf will
			* write out in 512 byte intervals */

			if (dotarbuf(tarhandle,data,datalen) != datalen) {
				DEBUG(0,("Error writing to tar file - %s\n", strerror(errno)));
				break;
			}
	      
			if (datalen == 0) {
				DEBUG(0,("Error reading file %s. Got 0 bytes\n", rname));
				break;
			}

			datalen=0;
		}

		/* pad tar file with zero's if we couldn't get entire file */
		if (nread < finfo.size) {
			DEBUG(0, ("Didn't get entire file. size=%.0f, nread=%d\n",
						(double)finfo.size, (int)nread));
			if (padit(data, sizeof(data), finfo.size - nread))
				DEBUG(0,("Error writing tar file - %s\n", strerror(errno)));
		}

		/* round tar file to nearest block */
		if (finfo.size % TBLOCK)
			dozerobuf(tarhandle, TBLOCK - (finfo.size % TBLOCK));
      
		ttarf+=finfo.size + TBLOCK - (finfo.size % TBLOCK);
		ntarf++;
	}
  
	cli_close(cli, fnum);

	if (shallitime) {
		struct timeval tp_end;
		int this_time;

		/* if shallitime is true then we didn't skip */
		if (tar_reset && !dry_run)
			(void) do_setrattr(finfo.name, aARCH, ATTRRESET);
      
		GetTimeOfDay(&tp_end);
		this_time = (tp_end.tv_sec - tp_start.tv_sec)*1000 + (tp_end.tv_usec - tp_start.tv_usec)/1000;
		get_total_time_ms += this_time;
		get_total_size += finfo.size;

		if (tar_noisy) {
			DEBUG(0, ("%12.0f (%7.1f kb/s) %s\n",
				(double)finfo.size, finfo.size / MAX(0.001, (1.024*this_time)),
				finfo.name));
		}

		/* Thanks to Carel-Jan Engel ([email protected]) for this one */
		DEBUG(3,("(%g kb/s) (average %g kb/s)\n",
				finfo.size / MAX(0.001, (1.024*this_time)),
				get_total_size / MAX(0.001, (1.024*get_total_time_ms))));
	}
}
Example #27
0
NTSTATUS cli_nt_establish_netlogon(struct cli_state *cli, int sec_chan,
				   const uchar trust_password[16])
{
	NTSTATUS result;	
	uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS;
	int fnum;

	cli_nt_netlogon_netsec_session_close(cli);

	if (lp_client_schannel() != False)
		neg_flags |= NETLOGON_NEG_SCHANNEL;

	result = cli_nt_setup_creds(cli, sec_chan, trust_password,
				    &neg_flags, 2);

	if (!NT_STATUS_IS_OK(result)) {
		cli_nt_session_close(cli);
		return result;
	}

	if ((lp_client_schannel() == True) &&
	    ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {

		DEBUG(3, ("Server did not offer schannel\n"));
		cli_nt_session_close(cli);
		return NT_STATUS_UNSUCCESSFUL;
	}

	if ((lp_client_schannel() == False) ||
	    ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
		return NT_STATUS_OK;
		
		/* keep the existing connection to NETLOGON open */

	}

	/* Server offered schannel, so try it. */

	memcpy(cli->auth_info.sess_key, cli->sess_key,
	       sizeof(cli->auth_info.sess_key));

	cli->saved_netlogon_pipe_fnum = cli->nt_pipe_fnum;

	cli->pipe_auth_flags = AUTH_PIPE_NETSEC;
	cli->pipe_auth_flags |= AUTH_PIPE_SIGN;
	cli->pipe_auth_flags |= AUTH_PIPE_SEAL;

	if (cli->capabilities & CAP_NT_SMBS) {

		/* The secure channel connection must be opened on the same 
                   session (TCP connection) as the one the challenge was
                   requested from. */
		if ((fnum = cli_nt_create(cli, PIPE_NETLOGON_PLAIN,
					  DESIRED_ACCESS_PIPE)) == -1) {
			DEBUG(0,("cli_nt_create failed to %s machine %s. "
				 "Error was %s\n",
				 PIPE_NETLOGON, cli->desthost,
				 cli_errstr(cli)));
			return NT_STATUS_UNSUCCESSFUL;
		}
		
		cli->nt_pipe_fnum = (uint16)fnum;
	} else {
		if ((fnum = cli_open(cli, PIPE_NETLOGON,
				     O_CREAT|O_RDWR, DENY_NONE)) == -1) {
			DEBUG(0,("cli_open failed on pipe %s to machine %s. "
				 "Error was %s\n",
				 PIPE_NETLOGON, cli->desthost,
				 cli_errstr(cli)));
			return NT_STATUS_UNSUCCESSFUL;
		}

		cli->nt_pipe_fnum = (uint16)fnum;

		/**************** Set Named Pipe State ***************/
		if (!rpc_pipe_set_hnd_state(cli, PIPE_NETLOGON, 0x4300)) {
			DEBUG(0,("Pipe hnd state failed.  Error was %s\n",
				  cli_errstr(cli)));
			cli_close(cli, cli->nt_pipe_fnum);
			return NT_STATUS_UNSUCCESSFUL;
		}
	}
	
	if (!rpc_pipe_bind(cli, PI_NETLOGON, global_myname())) {
		DEBUG(2,("rpc bind to %s failed\n", PIPE_NETLOGON));
		cli_close(cli, cli->nt_pipe_fnum);
		return NT_STATUS_UNSUCCESSFUL;
	}

	return NT_STATUS_OK;
}
Example #28
0
BOOL cli_nt_session_open(struct cli_state *cli, const int pipe_idx)
{
	int fnum;

	/* At the moment we can't have more than one pipe open over
           a cli connection. )-: */

	SMB_ASSERT(cli->nt_pipe_fnum == 0);
	
	/* The pipe index must fall within our array */

	SMB_ASSERT((pipe_idx >= 0) && (pipe_idx < PI_MAX_PIPES));

	if (cli->capabilities & CAP_NT_SMBS) {
		if ((fnum = cli_nt_create(cli, &pipe_names[pipe_idx].client_pipe[5], DESIRED_ACCESS_PIPE)) == -1) {
			DEBUG(0,("cli_nt_session_open: cli_nt_create failed on pipe %s to machine %s.  Error was %s\n",
				 &pipe_names[pipe_idx].client_pipe[5], cli->desthost, cli_errstr(cli)));
			return False;
		}

		cli->nt_pipe_fnum = (uint16)fnum;
	} else {
		if ((fnum = cli_open(cli, pipe_names[pipe_idx].client_pipe, O_CREAT|O_RDWR, DENY_NONE)) == -1) {
			DEBUG(1,("cli_nt_session_open: cli_open failed on pipe %s to machine %s.  Error was %s\n",
				 pipe_names[pipe_idx].client_pipe, cli->desthost, cli_errstr(cli)));
			return False;
		}

		cli->nt_pipe_fnum = (uint16)fnum;

		/**************** Set Named Pipe State ***************/
		if (!rpc_pipe_set_hnd_state(cli, pipe_names[pipe_idx].client_pipe, 0x4300)) {
			DEBUG(0,("cli_nt_session_open: pipe hnd state failed.  Error was %s\n",
				  cli_errstr(cli)));
			cli_close(cli, cli->nt_pipe_fnum);
			cli->nt_pipe_fnum = 0;
			return False;
		}
	}

	/******************* bind request on pipe *****************/

	if (!rpc_pipe_bind(cli, pipe_idx, global_myname())) {
		DEBUG(2,("cli_nt_session_open: rpc bind to %s failed\n",
			 get_pipe_name_from_index(pipe_idx)));
		cli_close(cli, cli->nt_pipe_fnum);
		cli->nt_pipe_fnum = 0;
		return False;
	}

	cli->pipe_idx = pipe_idx;

	/* 
	 * Setup the remote server name prefixed by \ and the machine account name.
	 */

	fstrcpy(cli->srv_name_slash, "\\\\");
	fstrcat(cli->srv_name_slash, cli->desthost);
	strupper_m(cli->srv_name_slash);

	fstrcpy(cli->clnt_name_slash, "\\\\");
	fstrcat(cli->clnt_name_slash, global_myname());
	strupper_m(cli->clnt_name_slash);

	fstrcpy(cli->mach_acct, global_myname());
	fstrcat(cli->mach_acct, "$");
	strupper_m(cli->mach_acct);

	/* Remember which pipe we're talking to */
	fstrcpy(cli->pipe_name, pipe_names[pipe_idx].client_pipe);

	return True;
}
Example #29
0
/*************************************************************
change a password on a remote machine using IPC calls
*************************************************************/
BOOL remote_password_change(const char *remote_machine, const char *user_name, 
			    const char *old_passwd, const char *new_passwd,
			    char *err_str, size_t err_str_len)
{
	struct nmb_name calling, called;
	struct cli_state cli;
	struct in_addr ip;

	*err_str = '\0';

	if(!resolve_name( remote_machine, &ip, 0x20)) {
		slprintf(err_str, err_str_len-1, "unable to find an IP address for machine %s.\n",
			remote_machine );
		return False;
	}
 
	ZERO_STRUCT(cli);
 
	if (!cli_initialise(&cli) || !cli_connect(&cli, remote_machine, &ip)) {
		slprintf(err_str, err_str_len-1, "unable to connect to SMB server on machine %s. Error was : %s.\n",
			remote_machine, cli_errstr(&cli) );
		return False;
	}
  
	make_nmb_name(&calling, global_myname() , 0x0);
	make_nmb_name(&called , remote_machine, 0x20);
	
	if (!cli_session_request(&cli, &calling, &called)) {
		slprintf(err_str, err_str_len-1, "machine %s rejected the session setup. Error was : %s.\n",
			remote_machine, cli_errstr(&cli) );
		cli_shutdown(&cli);
		return False;
	}
  
	cli.protocol = PROTOCOL_NT1;

	if (!cli_negprot(&cli)) {
		slprintf(err_str, err_str_len-1, "machine %s rejected the negotiate protocol. Error was : %s.\n",        
			remote_machine, cli_errstr(&cli) );
		cli_shutdown(&cli);
		return False;
	}
  
	/*
	 * We should connect as the anonymous user here, in case
	 * the server has "must change password" checked...
	 * Thanks to <*****@*****.**> for this fix.
	 */

	if (!cli_session_setup(&cli, "", "", 0, "", 0, "")) {
		slprintf(err_str, err_str_len-1, "machine %s rejected the session setup. Error was : %s.\n",        
			remote_machine, cli_errstr(&cli) );
		cli_shutdown(&cli);
		return False;
	}               

	if (!cli_send_tconX(&cli, "IPC$", "IPC", "", 1)) {
		slprintf(err_str, err_str_len-1, "machine %s rejected the tconX on the IPC$ share. Error was : %s.\n",
			remote_machine, cli_errstr(&cli) );
		cli_shutdown(&cli);
		return False;
	}

	if(!cli_oem_change_password(&cli, user_name, new_passwd, old_passwd)) {
		slprintf(err_str, err_str_len-1, "machine %s rejected the password change: Error was : %s.\n",
			remote_machine, cli_errstr(&cli) );
		cli_shutdown(&cli);
		return False;
	}
	
	cli_shutdown(&cli);
	return True;
}
Example #30
0
NTSTATUS change_trust_account_password( const char *domain, const char *remote_machine)
{
	NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
	struct in_addr pdc_ip;
	fstring dc_name;
	struct cli_state *cli;

	DEBUG(5,("change_trust_account_password: Attempting to change trust account password in domain %s....\n",
		domain));

	if (remote_machine == NULL || !strcmp(remote_machine, "*")) {
		/* Use the PDC *only* for this */
	
		if ( !get_pdc_ip(domain, &pdc_ip) ) {
			DEBUG(0,("Can't get IP for PDC for domain %s\n", domain));
			goto failed;
		}

		if ( !name_status_find( domain, 0x1b, 0x20, pdc_ip, dc_name) )
			goto failed;
	} else {
		/* supoport old deprecated "smbpasswd -j DOMAIN -r MACHINE" behavior */
		fstrcpy( dc_name, remote_machine );
	}
	
	/* if this next call fails, then give up.  We can't do
	   password changes on BDC's  --jerry */
	   
	if (!NT_STATUS_IS_OK(cli_full_connection(&cli, global_myname(), dc_name, 
					   NULL, 0,
					   "IPC$", "IPC",  
					   "", "",
					   "", 0, Undefined, NULL))) {
		DEBUG(0,("modify_trust_password: Connection to %s failed!\n", dc_name));
		nt_status = NT_STATUS_UNSUCCESSFUL;
		goto failed;
	}
      
	/*
	 * Ok - we have an anonymous connection to the IPC$ share.
	 * Now start the NT Domain stuff :-).
	 */

	if(cli_nt_session_open(cli, PI_NETLOGON) == False) {
		DEBUG(0,("modify_trust_password: unable to open the domain client session to machine %s. Error was : %s.\n", 
			dc_name, cli_errstr(cli)));
		cli_nt_session_close(cli);
		cli_ulogoff(cli);
		cli_shutdown(cli);
		nt_status = NT_STATUS_UNSUCCESSFUL;
		goto failed;
	}

	nt_status = trust_pw_find_change_and_store_it(cli, cli->mem_ctx, domain);
  
	cli_nt_session_close(cli);
	cli_ulogoff(cli);
	cli_shutdown(cli);
	
failed:
	if (!NT_STATUS_IS_OK(nt_status)) {
		DEBUG(0,("%s : change_trust_account_password: Failed to change password for domain %s.\n", 
			timestring(False), domain));
	}
	else
		DEBUG(5,("change_trust_account_password: sucess!\n"));
  
	return nt_status;
}