From 66d5d73a5d75e88a77970f7b27687b8354ab2e80 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 25 Sep 1998 21:01:52 +0000 Subject: added rpcclient program (This used to be commit aa38f39d67fade4dfd7badb7a9b39c833a1dd1ca) --- source3/Makefile.in | 23 +- source3/bin/.cvsignore | 1 + source3/include/nameserv.h | 7 - source3/include/ntdomain.h | 7 +- source3/include/proto.h | 52 ++- source3/include/smb.h | 205 ++++++++-- source3/lib/util.c | 40 ++ source3/libsmb/clientgen.c | 173 ++++++++- source3/libsmb/pwd_cache.c | 236 ++++++++++++ source3/libsmb/smbencrypt.c | 35 ++ source3/nmbd/nmbd_synclists.c | 8 +- source3/rpc_client/cli_lsarpc.c | 20 +- source3/rpc_client/cli_netlogon.c | 16 +- source3/rpc_parse/parse_lsa.c | 91 +++++ source3/rpcclient/cmd_lsarpc.c | 119 ++++++ source3/rpcclient/cmd_netlogon.c | 108 ++++++ source3/rpcclient/cmd_samr.c | 584 +++++++++++++++++++++++++++++ source3/rpcclient/cmd_srvsvc.c | 329 ++++++++++++++++ source3/rpcclient/cmd_wkssvc.c | 96 +++++ source3/rpcclient/rpcclient.c | 770 ++++++++++++++++++++++++++++++++++++++ source3/smbd/password.c | 15 +- source3/ubiqx/sys_include.h | 2 +- source3/utils/smbpasswd.c | 8 +- 23 files changed, 2856 insertions(+), 89 deletions(-) create mode 100644 source3/libsmb/pwd_cache.c create mode 100644 source3/rpcclient/cmd_lsarpc.c create mode 100644 source3/rpcclient/cmd_netlogon.c create mode 100644 source3/rpcclient/cmd_samr.c create mode 100644 source3/rpcclient/cmd_srvsvc.c create mode 100644 source3/rpcclient/cmd_wkssvc.c create mode 100644 source3/rpcclient/rpcclient.c (limited to 'source3') diff --git a/source3/Makefile.in b/source3/Makefile.in index 16f94789d3..3665fc7a3d 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -74,7 +74,7 @@ FLAGS = $(FLAGS5) $(PASSWD_FLAGS) SPROGS = bin/smbd bin/nmbd bin/swat PROGS1 = bin/smbclient bin/testparm bin/testprns bin/smbrun bin/smbstatus -PROGS2 = bin/smbpasswd bin/make_smbcodepage +PROGS2 = bin/rpcclient bin/smbpasswd bin/make_smbcodepage PROGS = $(PROGS1) $(PROGS2) bin/nmblookup bin/make_printerdef SCRIPTS = script/smbtar script/addtosmbpass @@ -89,7 +89,7 @@ LIB_OBJ = lib/charcnv.o lib/charset.o lib/debug.o lib/fault.o \ lib/membuffer.o lib/netmask.o lib/pidfile.o lib/replace.o \ lib/signal.o lib/slprintf.o lib/system.o lib/time.o lib/ufc.o \ lib/util.o lib/genrand.o lib/username.o lib/access.o lib/smbrun.o \ - lib/bitmap.o + lib/bitmap.o UBIQX_OBJ = ubiqx/ubi_BinTree.o ubiqx/ubi_Cache.o ubiqx/ubi_SplayTree.o \ ubiqx/ubi_dLinkList.o ubiqx/ubi_sLinkList.o @@ -98,7 +98,7 @@ PARAM_OBJ = param/loadparm.o param/params.o LIBSMB_OBJ = libsmb/clientgen.o libsmb/namequery.o libsmb/nmblib.o \ libsmb/nterr.o libsmb/smbdes.o libsmb/smbencrypt.o \ - libsmb/smberr.o libsmb/credentials.o + libsmb/smberr.o libsmb/credentials.o libsmb/pwd_cache.o RPC_SERVER_OBJ = rpc_server/srv_ldap_helpers.o rpc_server/srv_lsa.o \ rpc_server/srv_lsa_hnd.o rpc_server/srv_netlog.o \ @@ -113,7 +113,7 @@ RPC_PARSE_OBJ = rpc_parse/parse_lsa.o rpc_parse/parse_misc.o \ rpc_parse/parse_wks.o RPC_CLIENT_OBJ = rpc_client/cli_login.o rpc_client/cli_netlogon.o \ - rpc_client/cli_pipe.o + rpc_client/cli_pipe.o rpc_client/cli_lsarpc.o LOCKING_OBJ = locking/locking.o locking/locking_shm.o locking/locking_slow.o \ locking/shmem.o locking/shmem_sysv.o @@ -177,6 +177,15 @@ TESTPRNS_OBJ = utils/testprns.o $(PARAM_OBJ) $(PRINTING_OBJ) $(UBIQX_OBJ) \ SMBPASSWD_OBJ = utils/smbpasswd.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(PASSDB_OBJ) \ $(UBIQX_OBJ) $(RPC_CLIENT_OBJ) $(RPC_PARSE_OBJ) $(LIB_OBJ) +RPCCLIENT_OBJ = rpcclient/rpcclient.o \ + rpcclient/cmd_lsarpc.o \ + $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) \ + $(RPC_CLIENT_OBJ) $(RPC_PARSE_OBJ) $(PASSDB_OBJ) +# rpcclient/cmd_netlogon.o \ +# rpcclient/cmd_samr.o \ +# rpcclient/cmd_srvsvc.o \ +# rpcclient/cmd_wkssvc.o \ + CLIENT_OBJ = client/client.o client/clientutil.o client/clitar.o \ $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) @@ -186,7 +195,7 @@ NMBLOOKUP_OBJ = utils/nmblookup.o $(PARAM_OBJ) $(UBIQX_OBJ) \ SMBTORTURE_OBJ = utils/torture.o $(LIBSMB_OBJ) $(PARAM_OBJ) \ $(UBIQX_OBJ) $(LIB_OBJ) -PROTO_OBJ = $(SMBD_OBJ) $(NMBD_OBJ) $(SWAT_OBJ) $(CLIENT_OBJ) +PROTO_OBJ = $(SMBD_OBJ) $(NMBD_OBJ) $(SWAT_OBJ) $(CLIENT_OBJ) $(RPCCLIENT_OBJ) ###################################################################### # now the rules... @@ -224,6 +233,10 @@ bin/smbrun: $(SMBRUN_OBJ) @echo Linking $@ @$(CC) $(FLAGS) -o $@ $(SMBRUN_OBJ) $(LIBS) +bin/rpcclient: $(RPCCLIENT_OBJ) + @echo Linking $@ + @$(CC) $(FLAGS) -o $@ $(RPCCLIENT_OBJ) $(LIBS) + bin/smbclient: $(CLIENT_OBJ) @echo Linking $@ @$(CC) $(FLAGS) -o $@ $(CLIENT_OBJ) $(LIBS) diff --git a/source3/bin/.cvsignore b/source3/bin/.cvsignore index c141acdbc1..65115de4e0 100644 --- a/source3/bin/.cvsignore +++ b/source3/bin/.cvsignore @@ -12,3 +12,4 @@ smbtorture swat testparm testprns +rpcclient diff --git a/source3/include/nameserv.h b/source3/include/nameserv.h index e50ad042d9..e3a1d740a7 100644 --- a/source3/include/nameserv.h +++ b/source3/include/nameserv.h @@ -170,13 +170,6 @@ enum logon_state struct subnet_record; -/* A netbios name structure. */ -struct nmb_name { - char name[17]; - char scope[64]; - unsigned int name_type; -}; - struct nmb_data { uint16 nb_flags; /* Netbios flags. */ diff --git a/source3/include/ntdomain.h b/source3/include/ntdomain.h index ac411fa653..5cdd2849f8 100644 --- a/source3/include/ntdomain.h +++ b/source3/include/ntdomain.h @@ -81,13 +81,8 @@ typedef struct pipes_struct uint32 hdr_offsets; uint32 frag_len_left; uint32 next_frag_start; -} pipes_struct; -struct acct_info -{ - fstring acct_name; /* account name */ - uint32 smb_userid; /* domain-relative RID */ -}; +} pipes_struct; struct api_struct { diff --git a/source3/include/proto.h b/source3/include/proto.h index fd77c45ee3..d9ea40354f 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -226,6 +226,7 @@ BOOL in_group(gid_t group, int current_gid, int ngroups, GID_T *groups); char *StrCpy(char *dest,char *src); char *StrnCpy(char *dest,char *src,int n); void putip(void *dest,void *src); +char *dns_to_netbios_name(char *dns_name); int name_mangle( char *In, char *Out, char name_type ); BOOL file_exist(char *fname,SMB_STRUCT_STAT *sbuf); time_t file_modtime(char *fname); @@ -387,14 +388,20 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum, BOOL cli_oem_change_password(struct cli_state *cli, char *user, char *new_password, char *old_password); BOOL cli_negprot(struct cli_state *cli); -BOOL cli_session_request(struct cli_state *cli, char *host, int name_type, - char *myname); +BOOL cli_session_request(struct cli_state *cli, + struct nmb_name *calling, struct nmb_name *called); BOOL cli_connect(struct cli_state *cli, char *host, struct in_addr *ip); BOOL cli_initialise(struct cli_state *cli); void cli_shutdown(struct cli_state *cli); void cli_error(struct cli_state *cli, int *eclass, int *num); void cli_sockopt(struct cli_state *cli, char *options); int cli_setpid(struct cli_state *cli, int pid); +BOOL cli_reestablish_connection(struct cli_state *cli); +BOOL cli_establish_connection(struct cli_state *cli, + char *dest_host, struct in_addr *dest_ip, + struct nmb_name *calling, struct nmb_name *called, + char *service, char *service_type, + BOOL do_shutdown, BOOL do_tcon); /*The following definitions come from libsmb/credentials.c */ @@ -440,6 +447,20 @@ void sort_query_replies(char *data, int n, struct in_addr ip); char *get_nt_error_msg(uint32 nt_code); +/*The following definitions come from libsmb/pwd_cache.c */ + +void pwd_init(struct pwd_info *pwd); +void pwd_obfuscate_key(struct pwd_info *pwd, uint32 int_key, char *str_key); +void pwd_read(struct pwd_info *pwd, char *passwd_report, BOOL do_encrypt); +void pwd_set_nullpwd(struct pwd_info *pwd); +void pwd_set_cleartext(struct pwd_info *pwd, char *clr); +void pwd_get_cleartext(struct pwd_info *pwd, char *clr); +void pwd_set_lm_nt_16(struct pwd_info *pwd, char lm_pwd[16], char nt_pwd[16]); +void pwd_get_lm_nt_16(struct pwd_info *pwd, char lm_pwd[16], char nt_pwd[16]); +void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr); +void pwd_make_lm_nt_owf(struct pwd_info *pwd, char cryptkey[8]); +void pwd_get_lm_nt_owf(struct pwd_info *pwd, char lm_owf[24], char nt_owf[24]); + /*The following definitions come from libsmb/smbdes.c */ void E_P16(unsigned char *p14,unsigned char *p16); @@ -455,6 +476,8 @@ void SamOEMhash( unsigned char *data, unsigned char *key, int val); void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24); void E_md4hash(uchar *passwd, uchar *p16); +void nt_lm_owf_gen(char *pwd, uchar nt_p16[16], uchar p16[16]); +void SMBOWFencrypt(uchar passwd[16], uchar *c8, uchar p24[24]); void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24); /*The following definitions come from libsmb/smberr.c */ @@ -1162,6 +1185,15 @@ BOOL cli_nt_login_network(struct cli_state *cli, char *domain, char *username, NET_ID_INFO_CTR *ctr, NET_USER_INFO_3 *user_info3); BOOL cli_nt_logoff(struct cli_state *cli, NET_ID_INFO_CTR *ctr); +/*The following definitions come from rpc_client/cli_lsarpc.c */ + +BOOL do_lsa_open_policy(struct cli_state *cli, + char *server_name, POLICY_HND *hnd); +BOOL do_lsa_query_info_pol(struct cli_state *cli, + POLICY_HND *hnd, uint16 info_class, + fstring domain_name, fstring domain_sid); +BOOL do_lsa_close(struct cli_state *cli, POLICY_HND *hnd); + /*The following definitions come from rpc_client/cli_netlogon.c */ BOOL cli_net_logon_ctrl2(struct cli_state *cli, uint32 status_level); @@ -1184,8 +1216,13 @@ void cli_nt_session_close(struct cli_state *cli); /*The following definitions come from rpc_parse/parse_lsa.c */ void make_lsa_trans_name(LSA_TRANS_NAME *trn, uint32 sid_name_use, char *name, uint32 idx); +void make_lsa_obj_attr(LSA_OBJ_ATTR *attr, uint32 attributes, uint32 sec_qos); +void make_q_open_pol(LSA_Q_OPEN_POL *r_q, char *server_name, + uint32 attributes, uint32 sec_qos, + uint32 desired_access); void lsa_io_q_open_pol(char *desc, LSA_Q_OPEN_POL *r_q, prs_struct *ps, int depth); void lsa_io_r_open_pol(char *desc, LSA_R_OPEN_POL *r_p, prs_struct *ps, int depth); +void make_q_query(LSA_Q_QUERY_INFO *q_q, POLICY_HND *hnd, uint16 info_class); void lsa_io_q_query(char *desc, LSA_Q_QUERY_INFO *q_q, prs_struct *ps, int depth); void lsa_io_q_enum_trust_dom(char *desc, LSA_Q_ENUM_TRUST_DOM *q_e, prs_struct *ps, int depth); void make_r_enum_trust_dom(LSA_R_ENUM_TRUST_DOM *r_e, @@ -1197,6 +1234,9 @@ void lsa_io_q_lookup_sids(char *desc, LSA_Q_LOOKUP_SIDS *q_s, prs_struct *ps, in void lsa_io_r_lookup_sids(char *desc, LSA_R_LOOKUP_SIDS *r_s, prs_struct *ps, int depth); void lsa_io_q_lookup_rids(char *desc, LSA_Q_LOOKUP_RIDS *q_r, prs_struct *ps, int depth); void lsa_io_r_lookup_rids(char *desc, LSA_R_LOOKUP_RIDS *r_r, prs_struct *ps, int depth); +void make_lsa_q_close(LSA_Q_CLOSE *q_c, POLICY_HND *hnd); +void lsa_io_q_close(char *desc, LSA_Q_CLOSE *q_c, prs_struct *ps, int depth); +void lsa_io_r_close(char *desc, LSA_R_CLOSE *r_c, prs_struct *ps, int depth); /*The following definitions come from rpc_parse/parse_misc.c */ @@ -1629,6 +1669,14 @@ uint32 lookup_user_rid(char *user_name, uint32 *rid); BOOL api_wkssvc_rpc(pipes_struct *p, prs_struct *data); +/*The following definitions come from rpcclient/cmd_lsarpc.c */ + +void cmd_lsa_query_info(struct client_info *info); + +/*The following definitions come from rpcclient/rpcclient.c */ + +void rpcclient_init(void); + /*The following definitions come from smbd/blocking.c */ BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout, int lock_num); diff --git a/source3/include/smb.h b/source3/include/smb.h index bec14ddd13..59a7a07e76 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -403,42 +403,20 @@ typedef struct cred_info UTIME timestamp; /* credential time-stamp */ } DOM_CRED; -struct cli_state { - int fd; - int cnum; - int pid; - int mid; - int uid; - int protocol; - int sec_mode; - int rap_error; - int privilages; - fstring eff_name; - fstring desthost; - char cryptkey[8]; - uint32 sesskey; - int serverzone; - uint32 servertime; - int readbraw_supported; - int writebraw_supported; - int timeout; - int max_xmit; - char *outbuf; - char *inbuf; - int bufsize; - int initialised; - /* - * Only used in NT domain calls. - */ - uint32 nt_error; /* NT RPC error code. */ - uint16 nt_pipe_fnum; /* Pipe handle. */ - unsigned char sess_key[16]; /* Current session key. */ - DOM_CRED clnt_cred; /* Client credential. */ - fstring mach_acct; /* MYNAME$. */ - fstring srv_name_slash; /* \\remote server. */ - fstring clnt_name_slash; /* \\local client. */ -}; +struct pwd_info +{ + BOOL null_pwd; + BOOL cleartext; + BOOL crypted; + fstring password; + + uchar smb_lm_pwd[16]; + uchar smb_nt_pwd[16]; + + uchar smb_lm_owf[24]; + uchar smb_nt_owf[24]; +}; typedef struct { @@ -1601,6 +1579,161 @@ extern int unix_ERR_code; __FILE__, __LINE__)), smb_panic("assert failed"))) #define SMB_ASSERT_ARRAY(a,n) SMB_ASSERT((sizeof(a)/sizeof((a)[0])) >= (n)) +#include "ntdomain.h" + +/* A netbios name structure. */ +struct nmb_name { + char name[17]; + char scope[64]; + unsigned int name_type; +}; + +struct cli_state { + int fd; + int cnum; + int pid; + int mid; + int uid; + int protocol; + int sec_mode; + int rap_error; + int privilages; + + fstring eff_name; + fstring desthost; + fstring user_name; + fstring domain; + + fstring share; + fstring dev; + struct nmb_name called; + struct nmb_name calling; + fstring full_dest_host_name; + struct in_addr dest_ip; + + struct pwd_info pwd; + char cryptkey[8]; + uint32 sesskey; + int serverzone; + uint32 servertime; + int readbraw_supported; + int writebraw_supported; + int timeout; + int max_xmit; + char *outbuf; + char *inbuf; + int bufsize; + int initialised; + /* + * Only used in NT domain calls. + */ + uint32 nt_error; /* NT RPC error code. */ + uint16 nt_pipe_fnum; /* Pipe handle. */ + unsigned char sess_key[16]; /* Current session key. */ + DOM_CRED clnt_cred; /* Client credential. */ + fstring mach_acct; /* MYNAME$. */ + fstring srv_name_slash; /* \\remote server. */ + fstring clnt_name_slash; /* \\local client. */ +}; + +struct acct_info +{ + fstring acct_name; /* account name */ + uint32 smb_userid; /* domain-relative RID */ +}; + +struct nt_client_info +{ + /************* \PIPE\NETLOGON stuff ******************/ + + fstring mach_acct; + + uint8 sess_key[16]; + DOM_CRED clnt_cred; + DOM_CRED rtn_cred; + + NET_ID_INFO_CTR ctr; + NET_USER_INFO_3 user_info3; + + /************** \PIPE\lsarpc stuff ********************/ + + POLICY_HND lsa_info_pol; + + /* domain member */ + fstring level3_dom; + fstring level3_sid; + + /* domain controller */ + fstring level5_dom; + fstring level5_sid; + + /************** \PIPE\samr stuff ********************/ + + POLICY_HND samr_pol_connect; + POLICY_HND samr_pol_open_domain; + POLICY_HND samr_pol_open_user; + + struct acct_info *sam; + int num_sam_entries; +}; + + +struct tar_client_info +{ + int blocksize; + BOOL inc; + BOOL reset; + BOOL excl; + char type; + int attrib; + char **cliplist; + int clipn; + int tp; + int num_files; + int buf_size; + int bytes_written; + char *buf; + int handle; + int print_mode; + char *file_mode; +}; + +struct client_info +{ + struct in_addr dest_ip; + fstring dest_host; + fstring query_host; + uint8 name_type; + + fstring myhostname; + fstring mach_acct; + + pstring cur_dir; + pstring base_dir; + pstring file_sel; + + fstring service; + fstring share; + fstring svc_type; + + time_t newer_than; + int archive_level; + int dir_total; + int put_total_time_ms; + int put_total_size; + int get_total_time_ms; + int get_total_size; + int print_mode; + BOOL translation; + BOOL recurse_dir; + BOOL prompt; + BOOL lowercase; + BOOL abort_mget; + + struct tar_client_info tar; + struct nt_client_info dom; +}; + /* * Size of new password account encoding string. DO NOT CHANGE. */ @@ -1609,6 +1742,4 @@ extern int unix_ERR_code; #endif /* _SMB_H */ -#include "ntdomain.h" - /* _SMB_H */ diff --git a/source3/lib/util.c b/source3/lib/util.c index 0142c25052..8569881b3f 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -404,6 +404,46 @@ void putip(void *dest,void *src) } +#define TRUNCATE_NETBIOS_NAME 1 + +/******************************************************************* + convert, possibly using a stupid microsoft-ism which has destroyed + the transport independence of netbios (for CIFS vendors that usually + use the Win95-type methods, not for NT to NT communication, which uses + DCE/RPC and therefore full-length unicode strings...) a dns name into + a netbios name. + + the netbios name (NOT necessarily null-terminated) is truncated to 15 + characters. + + ******************************************************************/ +char *dns_to_netbios_name(char *dns_name) +{ + static char netbios_name[16]; + int i; + StrnCpy(netbios_name, dns_name, 15); + netbios_name[15] = 0; + +#ifdef TRUNCATE_NETBIOS_NAME + /* ok. this is because of a stupid microsoft-ism. if the called host + name contains a '.', microsoft clients expect you to truncate the + netbios name up to and including the '.' this even applies, by + mistake, to workgroup (domain) names, which is _really_ daft. + */ + for (i = 15; i >= 0; i--) + { + if (netbios_name[i] == '.') + { + netbios_name[i] = 0; + break; + } + } +#endif /* TRUNCATE_NETBIOS_NAME */ + + return netbios_name; +} + + /**************************************************************************** interpret the weird netbios "name". Return the name type ****************************************************************************/ diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index c85de92989..89caad419f 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1604,31 +1604,26 @@ BOOL cli_negprot(struct cli_state *cli) /**************************************************************************** - send a session request + send a session request. see rfc1002.txt 4.3 and 4.3.2 ****************************************************************************/ -BOOL cli_session_request(struct cli_state *cli, char *host, int name_type, - char *myname) +BOOL cli_session_request(struct cli_state *cli, + struct nmb_name *calling, struct nmb_name *called) { - fstring dest; char *p; int len = 4; /* send a session request (RFC 1002) */ - fstrcpy(dest,host); + memcpy(&(cli->calling), calling, sizeof(*calling)); + memcpy(&(cli->called ), called , sizeof(*called )); - p = strchr(dest,'.'); - if (p) *p = 0; - - fstrcpy(cli->desthost, dest); - /* put in the destination name */ p = cli->outbuf+len; - name_mangle(dest,p,name_type); + name_mangle(cli->called .name, p, cli->called .name_type); len += name_len(p); /* and my name */ p = cli->outbuf+len; - name_mangle(myname,p,0); + name_mangle(cli->calling.name, p, cli->calling.name_type); len += name_len(p); /* setup the packet length */ @@ -1754,3 +1749,157 @@ int cli_setpid(struct cli_state *cli, int pid) cli->pid = pid; return ret; } + +/**************************************************************************** +establishes a connection right up to doing tconX, reading in a password. +****************************************************************************/ +BOOL cli_reestablish_connection(struct cli_state *cli) +{ + struct nmb_name calling; + struct nmb_name called; + fstring dest_host; + struct in_addr dest_ip; + fstring share; + fstring dev; + BOOL do_tcon = False; + + if (!cli->initialised || cli->fd == -1) + { + DEBUG(3,("cli_reestablish_connection: not connected\n")); + return False; + } + + /* copy the parameters necessary to re-establish the connection */ + + if (cli->cnum != 0) + { + fstrcpy(share, cli->share); + fstrcpy(dev , cli->dev); + do_tcon = True; + } + + memcpy(&called , &(cli->called ), sizeof(called )); + memcpy(&calling, &(cli->calling), sizeof(calling)); + fstrcpy(dest_host, cli->full_dest_host_name); + dest_ip = cli->dest_ip; + + DEBUG(5,("cli_reestablish_connection: %s connecting to %s (ip %s) - %s [%s]\n", + namestr(&calling), namestr(&called), inet_ntoa(dest_ip), + cli->user_name, cli->domain)); + + return cli_establish_connection(cli, + dest_host, &dest_ip, + &calling, &called, + share, dev, False, do_tcon); +} + +/**************************************************************************** +establishes a connection right up to doing tconX, reading in a password. +****************************************************************************/ +BOOL cli_establish_connection(struct cli_state *cli, + char *dest_host, struct in_addr *dest_ip, + struct nmb_name *calling, struct nmb_name *called, + char *service, char *service_type, + BOOL do_shutdown, BOOL do_tcon) +{ + DEBUG(5,("cli_establish_connection: %s connecting to %s (%s) - %s [%s]\n", + namestr(calling), namestr(called), inet_ntoa(*dest_ip), + cli->user_name, cli->domain)); + + /* establish connection */ + + if ((!cli->initialised)) + { + return False; + } + + if (cli->fd == -1) + { + if (!cli_connect(cli, dest_host, dest_ip)) + { + DEBUG(1,("cli_establish_connection: failed to connect to %s (%s)\n", + namestr(calling), inet_ntoa(*dest_ip))); + return False; + } + } + + if (!cli_session_request(cli, calling, called)) + { + DEBUG(1,("failed session request\n")); + if (do_shutdown) cli_shutdown(cli); + return False; + } + + if (!cli_negprot(cli)) + { + DEBUG(1,("failed negprot\n")); + if (do_shutdown) cli_shutdown(cli); + return False; + } + + if (cli->pwd.cleartext || cli->pwd.null_pwd) + { + /* attempt clear-text session */ + + fstring passwd; + + pwd_get_cleartext(&(cli->pwd), passwd); + + /* attempt clear-text session */ + if (!cli_session_setup(cli, cli->user_name, + passwd, strlen(passwd), + NULL, 0, + cli->domain)) + { + DEBUG(1,("failed session setup\n")); + if (do_shutdown) cli_shutdown(cli); + return False; + } + if (do_tcon) + { + if (!cli_send_tconX(cli, service, service_type, + (char*)passwd, strlen(passwd))) + { + DEBUG(1,("failed tcon_X\n")); + if (do_shutdown) cli_shutdown(cli); + return False; + } + } + } + else + { + /* attempt encrypted session */ + uchar nt_sess_pwd[24]; + uchar lm_sess_pwd[24]; + + /* creates (storing a copy of) and then obtains a 24 byte password OWF */ + pwd_make_lm_nt_owf(&(cli->pwd), cli->cryptkey); + pwd_get_lm_nt_owf(&(cli->pwd), lm_sess_pwd, nt_sess_pwd); + + /* attempt encrypted session */ + if (!cli_session_setup(cli, cli->user_name, + (char*)lm_sess_pwd, sizeof(lm_sess_pwd), + nt_sess_pwd, sizeof(nt_sess_pwd), + cli->domain)) + { + DEBUG(1,("failed session setup\n")); + if (do_shutdown) cli_shutdown(cli); + return False; + } + + if (do_tcon) + { + if (!cli_send_tconX(cli, service, service_type, + (char*)nt_sess_pwd, sizeof(nt_sess_pwd))) + { + DEBUG(1,("failed tcon_X\n")); + if (do_shutdown) cli_shutdown(cli); + return False; + } + } + } + + if (do_shutdown) cli_shutdown(cli); + + return True; +} diff --git a/source3/libsmb/pwd_cache.c b/source3/libsmb/pwd_cache.c new file mode 100644 index 0000000000..e799a5458c --- /dev/null +++ b/source3/libsmb/pwd_cache.c @@ -0,0 +1,236 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + Password cacheing. obfuscation is planned + Copyright (C) Luke Kenneth Casson Leighton 1996-1998 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +extern int DEBUGLEVEL; + + +/**************************************************************************** +initialises a password structure +****************************************************************************/ +void pwd_init(struct pwd_info *pwd) +{ + bzero(pwd->password , sizeof(pwd->password )); + bzero(pwd->smb_lm_pwd, sizeof(pwd->smb_lm_pwd)); + bzero(pwd->smb_nt_pwd, sizeof(pwd->smb_nt_pwd)); + bzero(pwd->smb_lm_owf, sizeof(pwd->smb_lm_owf)); + bzero(pwd->smb_nt_owf, sizeof(pwd->smb_nt_owf)); + + pwd->null_pwd = True; /* safest option... */ + pwd->cleartext = False; + pwd->crypted = False; +} + +/**************************************************************************** +de-obfuscates a password +****************************************************************************/ +static void pwd_deobfuscate(struct pwd_info *pwd) +{ +} + +/**************************************************************************** +obfuscates a password +****************************************************************************/ +static void pwd_obfuscate(struct pwd_info *pwd) +{ +} + +/**************************************************************************** +sets the obfuscation key info +****************************************************************************/ +void pwd_obfuscate_key(struct pwd_info *pwd, uint32 int_key, char *str_key) +{ +} + +/**************************************************************************** +reads a password +****************************************************************************/ +void pwd_read(struct pwd_info *pwd, char *passwd_report, BOOL do_encrypt) +{ + /* grab a password */ + char *user_pass; + + pwd_init(pwd); + + user_pass = (char*)getpass(passwd_report); + + if (user_pass == NULL || user_pass[0] == 0) + { + pwd_set_nullpwd(pwd); + } + else if (do_encrypt) + { + pwd_make_lm_nt_16(pwd, user_pass); + } + else + { + pwd_set_cleartext(pwd, user_pass); + } +} + +/**************************************************************************** + stores a cleartext password + ****************************************************************************/ +void pwd_set_nullpwd(struct pwd_info *pwd) +{ + pwd_init(pwd); + + pwd->cleartext = False; + pwd->null_pwd = True; + pwd->crypted = False; +} + +/**************************************************************************** + stores a cleartext password + ****************************************************************************/ +void pwd_set_cleartext(struct pwd_info *pwd, char *clr) +{ + pwd_init(pwd); + fstrcpy(pwd->password, clr); + pwd->cleartext = True; + pwd->null_pwd = False; + pwd->crypted = False; + + pwd_obfuscate(pwd); +} + +/**************************************************************************** + gets a cleartext password + ****************************************************************************/ +void pwd_get_cleartext(struct pwd_info *pwd, char *clr) +{ + pwd_deobfuscate(pwd); + if (pwd->cleartext) + { + fstrcpy(clr, pwd->password); + } + else + { + clr[0] = 0; + } + pwd_obfuscate(pwd); +} + +/**************************************************************************** + stores lm and nt hashed passwords + ****************************************************************************/ +void pwd_set_lm_nt_16(struct pwd_info *pwd, char lm_pwd[16], char nt_pwd[16]) +{ + pwd_init(pwd); + + if (lm_pwd) + { + memcpy(pwd->smb_lm_pwd, lm_pwd, 16); + } + else + { + bzero(pwd->smb_lm_pwd, 16); + } + + if (nt_pwd) + { + memcpy(pwd->smb_nt_pwd, nt_pwd, 16); + } + else + { + bzero(pwd->smb_nt_pwd, 16); + } + + pwd->null_pwd = False; + pwd->cleartext = False; + pwd->crypted = False; + + pwd_obfuscate(pwd); +} + +/**************************************************************************** + gets lm and nt hashed passwords + ****************************************************************************/ +void pwd_get_lm_nt_16(struct pwd_info *pwd, char lm_pwd[16], char nt_pwd[16]) +{ + pwd_deobfuscate(pwd); + memcpy(lm_pwd, pwd->smb_lm_pwd, 16); + memcpy(nt_pwd, pwd->smb_nt_pwd, 16); + pwd_obfuscate(pwd); +} + +/**************************************************************************** + makes lm and nt hashed passwords + ****************************************************************************/ +void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr) +{ + pwd_init(pwd); + + nt_lm_owf_gen(clr, pwd->smb_nt_pwd, pwd->smb_lm_pwd); + pwd->null_pwd = False; + pwd->cleartext = False; + pwd->crypted = False; + + pwd_obfuscate(pwd); +} + +/**************************************************************************** + makes lm and nt OWF crypts + ****************************************************************************/ +void pwd_make_lm_nt_owf(struct pwd_info *pwd, char cryptkey[8]) +{ + pwd_deobfuscate(pwd); + +#ifdef DEBUG_PASSWORD + DEBUG(100,("client cryptkey: ")); + dump_data(100, cryptkey, 8); +#endif + + SMBOWFencrypt(pwd->smb_nt_pwd, cryptkey, pwd->smb_nt_owf); + +#ifdef DEBUG_PASSWORD + DEBUG(100,("nt_owf_passwd: ")); + dump_data(100, pwd->smb_nt_owf, sizeof(pwd->smb_nt_owf)); + DEBUG(100,("nt_sess_pwd: ")); + dump_data(100, pwd->smb_nt_pwd, sizeof(pwd->smb_nt_pwd)); +#endif + + SMBOWFencrypt(pwd->smb_lm_pwd, cryptkey, pwd->smb_lm_owf); + +#ifdef DEBUG_PASSWORD + DEBUG(100,("lm_owf_passwd: ")); + dump_data(100, pwd->smb_nt_owf, sizeof(pwd->smb_nt_owf)); + DEBUG(100,("lm_sess_pwd: ")); + dump_data(100, pwd->smb_lm_pwd, sizeof(pwd->smb_lm_pwd)); +#endif + + pwd->crypted = True; + + pwd_obfuscate(pwd); +} + +/**************************************************************************** + gets lm and nt crypts + ****************************************************************************/ +void pwd_get_lm_nt_owf(struct pwd_info *pwd, char lm_owf[24], char nt_owf[24]) +{ + pwd_deobfuscate(pwd); + memcpy(lm_owf, pwd->smb_lm_owf, 24); + memcpy(nt_owf, pwd->smb_nt_owf, 24); + pwd_obfuscate(pwd); +} + diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 6840f2e2c8..5a946e22c9 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -97,6 +97,41 @@ void E_md4hash(uchar *passwd, uchar *p16) mdfour(p16, (unsigned char *)wpwd, len); } +/* Does both the NT and LM owfs of a user's password */ +void nt_lm_owf_gen(char *pwd, uchar nt_p16[16], uchar p16[16]) +{ + char passwd[130]; + StrnCpy(passwd, pwd, sizeof(passwd)-1); + + /* Calculate the MD4 hash (NT compatible) of the password */ + memset(nt_p16, '\0', 16); + E_md4hash((uchar *)passwd, nt_p16); + + /* Mangle the passwords into Lanman format */ + passwd[14] = '\0'; + strupper(passwd); + + /* Calculate the SMB (lanman) hash functions of the password */ + + memset(p16, '\0', 16); + E_P16((uchar *) passwd, (uchar *)p16); + + /* clear out local copy of user's password (just being paranoid). */ + bzero(passwd, sizeof(passwd)); +} + +/* Does the des encryption from the NT or LM MD4 hash. */ +void SMBOWFencrypt(uchar passwd[16], uchar *c8, uchar p24[24]) +{ + uchar p21[21]; + + memset(p21,'\0',21); + + memcpy(p21, passwd, 16); + E_P24(p21, c8, p24); +} + + /* Does the NT MD4 hash then des encryption. */ void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24) diff --git a/source3/nmbd/nmbd_synclists.c b/source3/nmbd/nmbd_synclists.c index dee64d501b..b6f54dccec 100644 --- a/source3/nmbd/nmbd_synclists.c +++ b/source3/nmbd/nmbd_synclists.c @@ -32,6 +32,7 @@ #include "smb.h" extern int DEBUGLEVEL; +extern pstring scope; struct sync_record { struct sync_record *next, *prev; @@ -69,13 +70,18 @@ static void sync_child(char *name, int nm_type, extern fstring local_machine; static struct cli_state cli; uint32 local_type = local ? SV_TYPE_LOCAL_LIST_ONLY : 0; + struct nmb_name called, calling; if (!cli_initialise(&cli) || !cli_connect(&cli, name, &ip)) { fclose(fp); return; } - if (!cli_session_request(&cli, name, nm_type, local_machine)) { + make_nmb_name(&calling, local_machine, 0x0 , scope); + make_nmb_name(&called , name , nm_type, scope); + + if (!cli_session_request(&cli, &calling, &called)) + { cli_shutdown(&cli); fclose(fp); return; diff --git a/source3/rpc_client/cli_lsarpc.c b/source3/rpc_client/cli_lsarpc.c index 6570903e79..2f9952f5cb 100644 --- a/source3/rpc_client/cli_lsarpc.c +++ b/source3/rpc_client/cli_lsarpc.c @@ -35,7 +35,7 @@ extern int DEBUGLEVEL; /**************************************************************************** do a LSA Open Policy ****************************************************************************/ -BOOL do_lsa_open_policy(struct cli_state *cli, int t_idx, uint16 fnum, +BOOL do_lsa_open_policy(struct cli_state *cli, char *server_name, POLICY_HND *hnd) { prs_struct rbuf; @@ -59,7 +59,7 @@ BOOL do_lsa_open_policy(struct cli_state *cli, int t_idx, uint16 fnum, lsa_io_q_open_pol("", &q_o, &buf, 0); /* send the data on \PIPE\ */ - if (rpc_api_pipe_req(cli, t_idx, fnum, LSA_OPENPOLICY, &buf, &rbuf)) + if (rpc_api_pipe_req(cli, LSA_OPENPOLICY, &buf, &rbuf)) { LSA_R_OPEN_POL r_o; BOOL p; @@ -91,7 +91,7 @@ BOOL do_lsa_open_policy(struct cli_state *cli, int t_idx, uint16 fnum, /**************************************************************************** do a LSA Query Info Policy ****************************************************************************/ -BOOL do_lsa_query_info_pol(struct cli_state *cli, int t_idx, uint16 fnum, +BOOL do_lsa_query_info_pol(struct cli_state *cli, POLICY_HND *hnd, uint16 info_class, fstring domain_name, fstring domain_sid) { @@ -116,7 +116,7 @@ BOOL do_lsa_query_info_pol(struct cli_state *cli, int t_idx, uint16 fnum, lsa_io_q_query("", &q_q, &buf, 0); /* send the data on \PIPE\ */ - if (rpc_api_pipe_req(cli, t_idx, fnum, LSA_QUERYINFOPOLICY, &buf, &rbuf)) + if (rpc_api_pipe_req(cli, LSA_QUERYINFOPOLICY, &buf, &rbuf)) { LSA_R_QUERY_INFO r_q; BOOL p; @@ -148,9 +148,8 @@ BOOL do_lsa_query_info_pol(struct cli_state *cli, int t_idx, uint16 fnum, { char *dom_name = unistrn2(r_q.dom.id3.uni_domain_name.buffer, r_q.dom.id3.uni_domain_name.uni_str_len); - char *dom_sid = dom_sid_to_string(&(r_q.dom.id3.dom_sid.sid)); fstrcpy(domain_name, dom_name); - pstrcpy(domain_sid , dom_sid); + sid_to_string(domain_sid, &(r_q.dom.id3.dom_sid.sid)); valid_response = True; break; @@ -159,9 +158,8 @@ BOOL do_lsa_query_info_pol(struct cli_state *cli, int t_idx, uint16 fnum, { char *dom_name = unistrn2(r_q.dom.id5.uni_domain_name.buffer, r_q.dom.id5.uni_domain_name.uni_str_len); - char *dom_sid = dom_sid_to_string(&(r_q.dom.id5.dom_sid.sid)); fstrcpy(domain_name, dom_name); - pstrcpy(domain_sid , dom_sid); + sid_to_string(domain_sid, &(r_q.dom.id5.dom_sid.sid)); valid_response = True; break; @@ -189,7 +187,7 @@ BOOL do_lsa_query_info_pol(struct cli_state *cli, int t_idx, uint16 fnum, /**************************************************************************** do a LSA Close ****************************************************************************/ -BOOL do_lsa_close(struct cli_state *cli, int t_idx, uint16 fnum, POLICY_HND *hnd) +BOOL do_lsa_close(struct cli_state *cli, POLICY_HND *hnd) { prs_struct rbuf; prs_struct buf; @@ -212,7 +210,7 @@ BOOL do_lsa_close(struct cli_state *cli, int t_idx, uint16 fnum, POLICY_HND *hnd lsa_io_q_close("", &q_c, &buf, 0); /* send the data on \PIPE\ */ - if (rpc_api_pipe_req(cli, t_idx, fnum, LSA_CLOSE, &buf, &rbuf)) + if (rpc_api_pipe_req(cli, LSA_CLOSE, &buf, &rbuf)) { LSA_R_CLOSE r_c; BOOL p; @@ -253,3 +251,5 @@ BOOL do_lsa_close(struct cli_state *cli, int t_idx, uint16 fnum, POLICY_HND *hnd return valid_close; } + + diff --git a/source3/rpc_client/cli_netlogon.c b/source3/rpc_client/cli_netlogon.c index 757c5166e8..9af2a05f27 100644 --- a/source3/rpc_client/cli_netlogon.c +++ b/source3/rpc_client/cli_netlogon.c @@ -30,6 +30,7 @@ #include "includes.h" extern int DEBUGLEVEL; +extern pstring scope; extern pstring global_myname; extern fstring global_myworkgroup; @@ -474,8 +475,8 @@ static BOOL modify_trust_password( char *domain, char *remote_machine, unsigned char orig_trust_passwd_hash[16], unsigned char new_trust_passwd_hash[16]) { - struct in_addr dest_ip; struct cli_state cli; + struct nmb_name calling, called; ZERO_STRUCT(cli); if(cli_initialise(&cli) == False) { @@ -483,24 +484,29 @@ static BOOL modify_trust_password( char *domain, char *remote_machine, return False; } - if(!resolve_name( remote_machine, &dest_ip)) { + if(!resolve_name( remote_machine, &cli.dest_ip)) { DEBUG(0,("modify_trust_password: Can't resolve address for %s\n", remote_machine)); return False; } - if (ismyip(dest_ip)) { + if (ismyip(cli.dest_ip)) { DEBUG(0,("modify_trust_password: Machine %s is one of our addresses. Cannot add \ to ourselves.\n", remote_machine)); return False; } - if (!cli_connect(&cli, remote_machine, &dest_ip)) { + if (!cli_connect(&cli, remote_machine, &cli.dest_ip)) { DEBUG(0,("modify_trust_password: unable to connect to SMB server on \ machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli) )); return False; } - if (!cli_session_request(&cli, remote_machine, 0x20, global_myname)) { + + make_nmb_name(&calling, global_myname , 0x0 , scope); + make_nmb_name(&called , remote_machine, 0x20, scope); + + if (!cli_session_request(&cli, &calling, &called)) + { DEBUG(0,("modify_trust_password: machine %s rejected the session setup. \ Error was : %s.\n", remote_machine, cli_errstr(&cli) )); cli_shutdown(&cli); diff --git a/source3/rpc_parse/parse_lsa.c b/source3/rpc_parse/parse_lsa.c index 0818057d48..9db41b58b6 100644 --- a/source3/rpc_parse/parse_lsa.c +++ b/source3/rpc_parse/parse_lsa.c @@ -101,6 +101,23 @@ static void lsa_io_dom_r_ref(char *desc, DOM_R_REF *r_r, prs_struct *ps, int de } +/******************************************************************* +makes an LSA_OBJ_ATTR structure. +********************************************************************/ +void make_lsa_obj_attr(LSA_OBJ_ATTR *attr, uint32 attributes, uint32 sec_qos) +{ + if (attr == NULL) return; + + DEBUG(5,("make_lsa_obj_attr\n")); + + attr->len = 0x18; /* length of object attribute block, in bytes */ + attr->ptr_root_dir = 0; + attr->ptr_obj_name = 0; + attr->attributes = attributes; + attr->ptr_sec_desc = 0; + attr->sec_qos = sec_qos; +} + /******************************************************************* reads or writes an LSA_OBJ_ATTR structure. ********************************************************************/ @@ -134,6 +151,25 @@ static void lsa_io_obj_attr(char *desc, LSA_OBJ_ATTR *attr, prs_struct *ps, int } } +/******************************************************************* +makes an LSA_Q_OPEN_POL structure. +********************************************************************/ +void make_q_open_pol(LSA_Q_OPEN_POL *r_q, char *server_name, + uint32 attributes, uint32 sec_qos, + uint32 desired_access) +{ + if (r_q == NULL) return; + + DEBUG(5,("make_open_pol\n")); + + r_q->ptr = 1; /* undocumented pointer */ + + make_unistr2 (&(r_q->uni_server_name), server_name, strlen(server_name)); + make_lsa_obj_attr(&(r_q->attr ), attributes, sec_qos); + + r_q->des_access = desired_access; +} + /******************************************************************* reads or writes an LSA_Q_OPEN_POL structure. ********************************************************************/ @@ -168,6 +204,20 @@ void lsa_io_r_open_pol(char *desc, LSA_R_OPEN_POL *r_p, prs_struct *ps, int dep prs_uint32("status", ps, depth, &(r_p->status)); } +/******************************************************************* +makes an LSA_Q_QUERY_INFO structure. +********************************************************************/ +void make_q_query(LSA_Q_QUERY_INFO *q_q, POLICY_HND *hnd, uint16 info_class) +{ + if (q_q == NULL || hnd == NULL) return; + + DEBUG(5,("make_q_query\n")); + + memcpy(&(q_q->pol), hnd, sizeof(q_q->pol)); + + q_q->info_class = info_class; +} + /******************************************************************* reads or writes an LSA_Q_QUERY_INFO structure. ********************************************************************/ @@ -478,3 +528,44 @@ void lsa_io_r_lookup_rids(char *desc, LSA_R_LOOKUP_RIDS *r_r, prs_struct *ps, i prs_uint32("status ", ps, depth, &(r_r->status)); } + +/******************************************************************* +makes an LSA_Q_CLOSE structure. +********************************************************************/ +void make_lsa_q_close(LSA_Q_CLOSE *q_c, POLICY_HND *hnd) +{ + if (q_c == NULL || hnd == NULL) return; + + DEBUG(5,("make_lsa_q_close\n")); + + memcpy(&(q_c->pol), hnd, sizeof(q_c->pol)); +} + +/******************************************************************* +reads or writes an LSA_Q_CLOSE structure. +********************************************************************/ +void lsa_io_q_close(char *desc, LSA_Q_CLOSE *q_c, prs_struct *ps, int depth) +{ + if (q_c == NULL) return; + + prs_debug(ps, depth, desc, "lsa_io_q_close"); + depth++; + + smb_io_pol_hnd("", &(q_c->pol), ps, depth); +} + +/******************************************************************* +reads or writes an LSA_R_CLOSE structure. +********************************************************************/ +void lsa_io_r_close(char *desc, LSA_R_CLOSE *r_c, prs_struct *ps, int depth) +{ + if (r_c == NULL) return; + + prs_debug(ps, depth, desc, "lsa_io_r_close"); + depth++; + + smb_io_pol_hnd("", &(r_c->pol), ps, depth); + + prs_uint32("status", ps, depth, &(r_c->status)); +} + diff --git a/source3/rpcclient/cmd_lsarpc.c b/source3/rpcclient/cmd_lsarpc.c new file mode 100644 index 0000000000..24edb20450 --- /dev/null +++ b/source3/rpcclient/cmd_lsarpc.c @@ -0,0 +1,119 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + NT Domain Authentication SMB / MSRPC client + Copyright (C) Andrew Tridgell 1994-1997 + Copyright (C) Luke Kenneth Casson Leighton 1996-1997 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + + +#ifdef SYSLOG +#undef SYSLOG +#endif + +#include "includes.h" +#include "nterr.h" + +extern int DEBUGLEVEL; + +#define DEBUG_TESTING + +extern struct cli_state *smb_cli; +extern int smb_tidx; + +extern FILE* out_hnd; + + +/**************************************************************************** +nt lsa query +****************************************************************************/ +void cmd_lsa_query_info(struct client_info *info) +{ + fstring srv_name; + + BOOL res = True; + + fstrcpy(info->dom.level3_dom, ""); + fstrcpy(info->dom.level3_sid, ""); + fstrcpy(info->dom.level5_dom, ""); + fstrcpy(info->dom.level5_sid, ""); + + fstrcpy(srv_name, "\\\\"); + fstrcat(srv_name, info->myhostname); + strupper(srv_name); + + DEBUG(4,("cmd_lsa_query_info: server:%s\n", srv_name)); + + DEBUG(5, ("cmd_lsa_query_info: smb_cli->fd:%d\n", smb_cli->fd)); + + /* open LSARPC session. */ + res = res ? cli_nt_session_open(smb_cli, PIPE_LSARPC, False) : False; + + /* lookup domain controller; receive a policy handle */ + res = res ? do_lsa_open_policy(smb_cli, + srv_name, + &info->dom.lsa_info_pol) : False; + + /* send client info query, level 3. receive domain name and sid */ + res = res ? do_lsa_query_info_pol(smb_cli, + &info->dom.lsa_info_pol, 0x03, + info->dom.level3_dom, + info->dom.level3_sid) : False; + + /* send client info query, level 5. receive domain name and sid */ + res = res ? do_lsa_query_info_pol(smb_cli, + &info->dom.lsa_info_pol, 0x05, + info->dom.level5_dom, + info->dom.level5_sid) : False; + + res = res ? do_lsa_close(smb_cli, &info->dom.lsa_info_pol) : False; + + /* close the session */ + cli_nt_session_close(smb_cli); + + if (res) + { + BOOL domain_something = False; + DEBUG(5,("cmd_lsa_query_info: query succeeded\n")); + + fprintf(out_hnd, "LSA Query Info Policy\n"); + + if (info->dom.level3_sid[0] != 0) + { + fprintf(out_hnd, "Domain Member - Domain: %s SID: %s\n", + info->dom.level3_dom, info->dom.level3_sid); + domain_something = True; + } + if (info->dom.level5_sid[0] != 0) + { + fprintf(out_hnd, "Domain Controller - Domain: %s SID: %s\n", + info->dom.level5_dom, info->dom.level5_sid); + domain_something = True; + } + if (!domain_something) + { + fprintf(out_hnd, "%s is not a Domain Member or Controller\n", + info->dest_host); + } + } + else + { + DEBUG(5,("cmd_lsa_query_info: query succeeded\n")); + } +} + diff --git a/source3/rpcclient/cmd_netlogon.c b/source3/rpcclient/cmd_netlogon.c new file mode 100644 index 0000000000..40bb257072 --- /dev/null +++ b/source3/rpcclient/cmd_netlogon.c @@ -0,0 +1,108 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + NT Domain Authentication SMB / MSRPC client + Copyright (C) Andrew Tridgell 1994-1997 + Copyright (C) Luke Kenneth Casson Leighton 1996-1997 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + + +#ifdef SYSLOG +#undef SYSLOG +#endif + +#include "includes.h" +#include "nterr.h" + +extern int DEBUGLEVEL; + +#define DEBUG_TESTING + +extern struct cli_state *smb_cli; + +extern FILE* out_hnd; + + +/**************************************************************************** +experimental nt login. +****************************************************************************/ +void cmd_netlogon_login_test(struct client_info *info) +{ + BOOL res = True; + + /* machine account passwords */ + pstring new_mach_pwd; + + /* initialisation */ + new_mach_pwd[0] = 0; + + DEBUG(5,("do_nt_login_test: %d\n", __LINE__)); + +#if 0 + /* check whether the user wants to change their machine password */ + res = res ? trust_account_check(info->dest_ip, info->dest_host, + info->myhostname, smb_cli->domain, + info->mach_acct, new_mach_pwd) : False; +#endif + /* open NETLOGON session. negotiate credentials */ + res = res ? do_nt_session_open(smb_cli, + info->dest_host, info->myhostname, + info->mach_acct, + smb_cli->user_name, smb_cli->domain, + info->dom.sess_key, &info->dom.clnt_cred) : False; + + /* change the machine password? */ + if (new_mach_pwd != NULL && new_mach_pwd[0] != 0) + { + res = res ? do_nt_srv_pwset(smb_cli, info->dom.lsarpc_fnum, + info->dom.sess_key, &info->dom.clnt_cred, &info->dom.rtn_cred, + new_mach_pwd, + info->dest_host, info->mach_acct, info->myhostname) : False; + } + + /* create the user-identification info */ + make_nt_login_interactive(&info->dom.ctr, + info->dom.sess_key, + smb_cli->domain, info->myhostname, + getuid(), smb_cli->user_name); + + /* do an NT login */ + res = res ? do_nt_login(smb_cli, info->dom.lsarpc_fnum, + info->dom.sess_key, &info->dom.clnt_cred, &info->dom.rtn_cred, + &info->dom.ctr, info->dest_host, info->myhostname, &info->dom.user_info3) : False; + + /* ok! you're logged in! do anything you like, then... */ + + /* do an NT logout */ + res = res ? do_nt_logoff(smb_cli, info->dom.lsarpc_fnum, + info->dom.sess_key, &info->dom.clnt_cred, &info->dom.rtn_cred, + &info->dom.ctr, info->dest_host, info->myhostname) : False; + + /* close the session */ + cli_nt_session_close(smb_cli); + + if (res) + { + DEBUG(5,("cmd_nt_login: login test succeeded\n")); + } + else + { + DEBUG(5,("cmd_nt_login: login test failed\n")); + } +} + diff --git a/source3/rpcclient/cmd_samr.c b/source3/rpcclient/cmd_samr.c new file mode 100644 index 0000000000..447f2c41d0 --- /dev/null +++ b/source3/rpcclient/cmd_samr.c @@ -0,0 +1,584 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + NT Domain Authentication SMB / MSRPC client + Copyright (C) Andrew Tridgell 1994-1997 + Copyright (C) Luke Kenneth Casson Leighton 1996-1997 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + + +#ifdef SYSLOG +#undef SYSLOG +#endif + +#include "includes.h" +#include "nterr.h" + +extern int DEBUGLEVEL; + +#define DEBUG_TESTING + +extern struct cli_state *smb_cli; +extern int smb_tidx; + +extern FILE* out_hnd; + + +/**************************************************************************** +experimental SAM encryted rpc test connection +****************************************************************************/ +void cmd_sam_test(struct client_info *info) +{ + fstring srv_name; + fstring sid; + fstring domain; + BOOL res = True; + + fstrcpy(sid , info->dom.level5_sid); + fstrcpy(domain, info->dom.level5_dom); + + if (strlen(sid) == 0) + { + fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n"); + return; + } + + strcpy(srv_name, "\\\\"); + strcat(srv_name, info->myhostname); + strupper(srv_name); + + + fprintf(out_hnd, "SAM Encryption Test\n"); + + /* open SAMR session. */ + res = res ? do_ntlm_session_open(smb_cli, smb_tidx, + PIPE_SAMR, &(info->dom.samr_fnum), + info->myhostname, domain) : False; + + /* close the session */ + do_session_close(smb_cli, smb_tidx, info->dom.samr_fnum); + + if (res) + { + DEBUG(5,("cmd_sam_test: succeeded\n")); + } + else + { + DEBUG(5,("cmd_sam_test: failed\n")); + } +} + + +/**************************************************************************** +experimental SAM users enum. +****************************************************************************/ +void cmd_sam_enum_users(struct client_info *info) +{ + fstring srv_name; + fstring sid; + fstring domain; + int user_idx; + BOOL res = True; + BOOL request_user_info = False; + BOOL request_group_info = False; + uint16 num_entries = 0; + uint16 unk_0 = 0x0; + uint16 acb_mask = 0; + uint16 unk_1 = 0x0; + uint32 admin_rid = 0x304; /* absolutely no idea. */ + fstring tmp; + + fstrcpy(sid , info->dom.level5_sid); + fstrcpy(domain, info->dom.level5_dom); + + if (strlen(sid) == 0) + { + fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n"); + return; + } + + strcpy(srv_name, "\\\\"); + strcat(srv_name, info->dest_host); + strupper(srv_name); + + /* a bad way to do token parsing... */ + if (next_token(NULL, tmp, NULL)) + { + request_user_info |= strequal(tmp, "-u"); + request_group_info |= strequal(tmp, "-g"); + } + + if (next_token(NULL, tmp, NULL)) + { + request_user_info |= strequal(tmp, "-u"); + request_group_info |= strequal(tmp, "-g"); + } + +#ifdef DEBUG_TESTING + if (next_token(NULL, tmp, NULL)) + { + num_entries = strtoul(tmp, (char**)NULL, 16); + } + + if (next_token(NULL, tmp, NULL)) + { + unk_0 = strtoul(tmp, (char**)NULL, 16); + } + + if (next_token(NULL, tmp, NULL)) + { + acb_mask = strtoul(tmp, (char**)NULL, 16); + } + + if (next_token(NULL, tmp, NULL)) + { + unk_1 = strtoul(tmp, (char**)NULL, 16); + } +#endif + + fprintf(out_hnd, "SAM Enumerate Users\n"); + fprintf(out_hnd, "From: %s To: %s Domain: %s SID: %s\n", + info->myhostname, srv_name, domain, sid); + +#ifdef DEBUG_TESTING + DEBUG(5,("Number of entries:%d unk_0:%04x acb_mask:%04x unk_1:%04x\n", + num_entries, unk_0, acb_mask, unk_1)); +#endif + + /* open SAMR session. negotiate credentials */ + res = res ? do_session_open(smb_cli, smb_tidx, PIPE_SAMR, &(info->dom.samr_fnum)) : False; + + /* establish a connection. */ + res = res ? do_samr_connect(smb_cli, smb_tidx, info->dom.samr_fnum, + srv_name, 0x00000020, + &info->dom.samr_pol_connect) : False; + + /* connect to the domain */ + res = res ? do_samr_open_domain(smb_cli, smb_tidx, info->dom.samr_fnum, + &info->dom.samr_pol_connect, admin_rid, sid, + &info->dom.samr_pol_open_domain) : False; + + /* read some users */ + res = res ? do_samr_enum_dom_users(smb_cli, smb_tidx, info->dom.samr_fnum, + &info->dom.samr_pol_open_domain, + num_entries, unk_0, acb_mask, unk_1, 0xffff, + info->dom.sam, &info->dom.num_sam_entries) : False; + + if (res && info->dom.num_sam_entries == 0) + { + fprintf(out_hnd, "No users\n"); + } + + if (request_user_info || request_group_info) + { + /* query all the users */ + user_idx = 0; + + while (res && user_idx < info->dom.num_sam_entries) + { + uint32 user_rid = info->dom.sam[user_idx].smb_userid; + SAM_USER_INFO_21 usr; + + fprintf(out_hnd, "User RID: %8x User Name: %s\n", + user_rid, + info->dom.sam[user_idx].acct_name); + + if (request_user_info) + { + /* send user info query, level 0x15 */ + if (get_samr_query_userinfo(smb_cli, smb_tidx, info->dom.samr_fnum, + &info->dom.samr_pol_open_domain, + 0x15, user_rid, &usr)) + { + display_sam_user_info_21(out_hnd, DISPLAY_TXT, ACTION_HEADER , &usr); + display_sam_user_info_21(out_hnd, DISPLAY_TXT, ACTION_ENUMERATE, &usr); + display_sam_user_info_21(out_hnd, DISPLAY_TXT, ACTION_FOOTER , &usr); + } + } + + if (request_group_info) + { + uint32 num_groups; + DOM_GID gid[LSA_MAX_GROUPS]; + + /* send user group query */ + if (get_samr_query_usergroups(smb_cli, smb_tidx, info->dom.samr_fnum, + &info->dom.samr_pol_open_domain, + user_rid, &num_groups, gid)) + { + display_group_rid_info(out_hnd, DISPLAY_TXT, ACTION_HEADER , num_groups, gid); + display_group_rid_info(out_hnd, DISPLAY_TXT, ACTION_ENUMERATE, num_groups, gid); + display_group_rid_info(out_hnd, DISPLAY_TXT, ACTION_FOOTER , num_groups, gid); + } + } + + user_idx++; + } + } + + res = res ? do_samr_close(smb_cli, smb_tidx, info->dom.samr_fnum, + &info->dom.samr_pol_connect) : False; + + res = res ? do_samr_close(smb_cli, smb_tidx, info->dom.samr_fnum, + &info->dom.samr_pol_open_domain) : False; + + /* close the session */ + do_session_close(smb_cli, smb_tidx, info->dom.samr_fnum); + + if (res) + { + DEBUG(5,("cmd_sam_enum_users: succeeded\n")); + } + else + { + DEBUG(5,("cmd_sam_enum_users: failed\n")); + } +} + + +/**************************************************************************** +experimental SAM user query. +****************************************************************************/ +void cmd_sam_query_user(struct client_info *info) +{ + fstring srv_name; + fstring sid; + fstring domain; + int user_idx; + BOOL res = True; + BOOL request_user_info = False; + BOOL request_group_info = False; + uint16 num_entries = 0; + uint16 unk_0 = 0x0; + uint16 unk_1 = 0x0; + uint32 admin_rid = 0x304; /* absolutely no idea. */ + uint16 acb_mask = 0; + fstring rid_str ; + fstring info_str; + uint32 user_rid = 0; + uint32 info_level = 0x15; + + SAM_USER_INFO_21 usr; + + fstrcpy(sid , info->dom.level5_sid); + fstrcpy(domain, info->dom.level5_dom); + + if (strlen(sid) == 0) + { + fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n"); + return; + } + + strcpy(srv_name, "\\\\"); + strcat(srv_name, info->dest_host); + strupper(srv_name); + + if (next_token(NULL, rid_str, NULL) && next_token(NULL, info_str, NULL)) + { + user_rid = strtoul(rid_str , (char**)NULL, 16); + info_level = strtoul(info_str, (char**)NULL, 10); + } + + fprintf(out_hnd, "SAM Query User: rid %x info level %d\n", + user_rid, info_level); + fprintf(out_hnd, "From: %s To: %s Domain: %s SID: %s\n", + info->myhostname, srv_name, domain, sid); + + /* open SAMR session. negotiate credentials */ + res = res ? do_session_open(smb_cli, smb_tidx, PIPE_SAMR, &(info->dom.samr_fnum)) : False; + + /* establish a connection. */ + res = res ? do_samr_connect(smb_cli, smb_tidx, info->dom.samr_fnum, + srv_name, 0x00000020, + &info->dom.samr_pol_connect) : False; + + /* connect to the domain */ + res = res ? do_samr_open_domain(smb_cli, smb_tidx, info->dom.samr_fnum, + &info->dom.samr_pol_connect, admin_rid, sid, + &info->dom.samr_pol_open_domain) : False; + + fprintf(out_hnd, "User RID: %8x User Name: %s\n", + user_rid, + info->dom.sam[user_idx].acct_name); + + /* send user info query, level */ + if (get_samr_query_userinfo(smb_cli, smb_tidx, info->dom.samr_fnum, + &info->dom.samr_pol_open_domain, + info_level, user_rid, &usr)) + { + if (info_level == 0x15) + { + display_sam_user_info_21(out_hnd, DISPLAY_TXT, ACTION_HEADER , &usr); + display_sam_user_info_21(out_hnd, DISPLAY_TXT, ACTION_ENUMERATE, &usr); + display_sam_user_info_21(out_hnd, DISPLAY_TXT, ACTION_FOOTER , &usr); + } + } + + res = res ? do_samr_close(smb_cli, smb_tidx, info->dom.samr_fnum, + &info->dom.samr_pol_connect) : False; + + res = res ? do_samr_close(smb_cli, smb_tidx, info->dom.samr_fnum, + &info->dom.samr_pol_open_domain) : False; + + /* close the session */ + do_session_close(smb_cli, smb_tidx, info->dom.samr_fnum); + + if (res) + { + DEBUG(5,("cmd_sam_query_user: succeeded\n")); + } + else + { + DEBUG(5,("cmd_sam_query_user: failed\n")); + } +} + + +/**************************************************************************** +experimental SAM groups query. +****************************************************************************/ +void cmd_sam_query_groups(struct client_info *info) +{ + fstring srv_name; + fstring sid; + fstring domain; + BOOL res = True; + fstring info_str; + uint32 switch_value = 2; + uint32 admin_rid = 0x304; /* absolutely no idea. */ + + fstrcpy(sid , info->dom.level5_sid); + fstrcpy(domain, info->dom.level5_dom); + + if (strlen(sid) == 0) + { + fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n"); + return; + } + + strcpy(srv_name, "\\\\"); + strcat(srv_name, info->dest_host); + strupper(srv_name); + + if (next_token(NULL, info_str, NULL)) + { + switch_value = strtoul(info_str, (char**)NULL, 10); + } + + fprintf(out_hnd, "SAM Query Groups: info level %d\n", switch_value); + fprintf(out_hnd, "From: %s To: %s Domain: %s SID: %s\n", + info->myhostname, srv_name, domain, sid); + + /* open SAMR session. negotiate credentials */ + res = res ? do_session_open(smb_cli, smb_tidx, PIPE_SAMR, &(info->dom.samr_fnum)) : False; + + /* establish a connection. */ + res = res ? do_samr_connect(smb_cli, smb_tidx, info->dom.samr_fnum, + srv_name, 0x00000020, + &info->dom.samr_pol_connect) : False; + + /* connect to the domain */ + res = res ? do_samr_open_domain(smb_cli, smb_tidx, info->dom.samr_fnum, + &info->dom.samr_pol_connect, admin_rid, sid, + &info->dom.samr_pol_open_domain) : False; + + /* send a samr 0x8 command */ + res = res ? do_samr_unknown_8(smb_cli, smb_tidx, info->dom.samr_fnum, + &info->dom.samr_pol_open_domain, switch_value) : False; + + res = res ? do_samr_close(smb_cli, smb_tidx, info->dom.samr_fnum, + &info->dom.samr_pol_connect) : False; + + res = res ? do_samr_close(smb_cli, smb_tidx, info->dom.samr_fnum, + &info->dom.samr_pol_open_domain) : False; + + /* close the session */ + do_session_close(smb_cli, smb_tidx, info->dom.samr_fnum); + + if (res) + { + DEBUG(5,("cmd_sam_query_groups: succeeded\n")); + } + else + { + DEBUG(5,("cmd_sam_query_groups: failed\n")); + } +} + + +/**************************************************************************** +experimental SAM aliases query. +****************************************************************************/ +void cmd_sam_enum_aliases(struct client_info *info) +{ + fstring srv_name; + fstring sid; + fstring domain; + int user_idx; + BOOL res = True; + BOOL res2 = True; + BOOL request_user_info = False; + BOOL request_alias_info = False; + uint16 num_entries = 0; + uint16 unk_0 = 0x0; + uint16 acb_mask = 0; + uint16 unk_1 = 0x0; + uint32 admin_rid = 0x304; /* absolutely no idea. */ + fstring tmp; + + uint32 num_aliases = 3; + uint32 alias_rid[3] = { DOMAIN_GROUP_RID_ADMINS, DOMAIN_GROUP_RID_USERS, DOMAIN_GROUP_RID_GUESTS }; + fstring alias_names [3]; + uint32 num_als_usrs[3]; + + fstrcpy(sid , info->dom.level5_sid); + fstrcpy(domain, info->dom.level5_dom); + + if (strlen(sid) == 0) + { + fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n"); + return; + } + + strcpy(srv_name, "\\\\"); + strcat(srv_name, info->dest_host); + strupper(srv_name); + + /* a bad way to do token parsing... */ + if (next_token(NULL, tmp, NULL)) + { + request_user_info |= strequal(tmp, "-u"); + request_alias_info |= strequal(tmp, "-g"); + } + + if (next_token(NULL, tmp, NULL)) + { + request_user_info |= strequal(tmp, "-u"); + request_alias_info |= strequal(tmp, "-g"); + } + + fprintf(out_hnd, "SAM Enumerate Aliases\n"); + fprintf(out_hnd, "From: %s To: %s Domain: %s SID: %s\n", + info->myhostname, srv_name, domain, sid); + + /* open SAMR session. negotiate credentials */ + res = res ? do_session_open(smb_cli, smb_tidx, PIPE_SAMR, &(info->dom.samr_fnum)) : False; + + /* establish a connection. */ + res = res ? do_samr_connect(smb_cli, smb_tidx, info->dom.samr_fnum, + srv_name, 0x00000020, + &info->dom.samr_pol_connect) : False; + + /* connect to the domain */ + res = res ? do_samr_open_domain(smb_cli, smb_tidx, info->dom.samr_fnum, + &info->dom.samr_pol_connect, admin_rid, sid, + &info->dom.samr_pol_open_domain) : False; + + /* send a query on the aliase */ + res = res ? do_samr_query_unknown_12(smb_cli, smb_tidx, info->dom.samr_fnum, + &info->dom.samr_pol_open_domain, admin_rid, num_aliases, alias_rid, + &num_aliases, alias_names, num_als_usrs) : False; + + if (res) + { + display_alias_name_info(out_hnd, DISPLAY_TXT, ACTION_HEADER , num_aliases, alias_names, num_als_usrs); + display_alias_name_info(out_hnd, DISPLAY_TXT, ACTION_ENUMERATE, num_aliases, alias_names, num_als_usrs); + display_alias_name_info(out_hnd, DISPLAY_TXT, ACTION_FOOTER , num_aliases, alias_names, num_als_usrs); + } + +#if 0 + + /* read some users */ + res = res ? do_samr_enum_dom_users(smb_cli, smb_tidx, info->dom.samr_fnum, + &info->dom.samr_pol_open_domain, + num_entries, unk_0, acb_mask, unk_1, 0xffff, + info->dom.sam, &info->dom.num_sam_entries) : False; + + if (res && info->dom.num_sam_entries == 0) + { + fprintf(out_hnd, "No users\n"); + } + + if (request_user_info || request_alias_info) + { + /* query all the users */ + user_idx = 0; + + while (res && user_idx < info->dom.num_sam_entries) + { + uint32 user_rid = info->dom.sam[user_idx].smb_userid; + SAM_USER_INFO_21 usr; + + fprintf(out_hnd, "User RID: %8x User Name: %s\n", + user_rid, + info->dom.sam[user_idx].acct_name); + + if (request_user_info) + { + /* send user info query, level 0x15 */ + if (get_samr_query_userinfo(smb_cli, smb_tidx, info->dom.samr_fnum, + &info->dom.samr_pol_open_domain, + 0x15, user_rid, &usr)) + { + display_sam_user_info_21(out_hnd, DISPLAY_TXT, ACTION_HEADER , &usr); + display_sam_user_info_21(out_hnd, DISPLAY_TXT, ACTION_ENUMERATE, &usr); + display_sam_user_info_21(out_hnd, DISPLAY_TXT, ACTION_FOOTER , &usr); + } + } + + if (request_alias_info) + { + uint32 num_aliases; + DOM_GID gid[LSA_MAX_GROUPS]; + + /* send user aliase query */ + if (get_samr_query_useraliases(smb_cli, smb_tidx, info->dom.samr_fnum, + &info->dom.samr_pol_open_domain, + user_rid, &num_aliases, gid)) + { + display_alias_info(out_hnd, DISPLAY_TXT, ACTION_HEADER , num_aliases, gid); + display_alias_info(out_hnd, DISPLAY_TXT, ACTION_ENUMERATE, num_aliases, gid); + display_alias_info(out_hnd, DISPLAY_TXT, ACTION_FOOTER , num_aliases, gid); + } + } + + user_idx++; + } + } +#endif + + res = res ? do_samr_close(smb_cli, smb_tidx, info->dom.samr_fnum, + &info->dom.samr_pol_connect) : False; + + res = res ? do_samr_close(smb_cli, smb_tidx, info->dom.samr_fnum, + &info->dom.samr_pol_open_domain) : False; + + /* close the session */ + do_session_close(smb_cli, smb_tidx, info->dom.samr_fnum); + + if (res) + { + DEBUG(5,("cmd_sam_enum_users: succeeded\n")); + } + else + { + DEBUG(5,("cmd_sam_enum_users: failed\n")); + } +} + + diff --git a/source3/rpcclient/cmd_srvsvc.c b/source3/rpcclient/cmd_srvsvc.c new file mode 100644 index 0000000000..8dc11bd29e --- /dev/null +++ b/source3/rpcclient/cmd_srvsvc.c @@ -0,0 +1,329 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + NT Domain Authentication SMB / MSRPC client + Copyright (C) Andrew Tridgell 1994-1997 + Copyright (C) Luke Kenneth Casson Leighton 1996-1997 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + + +#ifdef SYSLOG +#undef SYSLOG +#endif + +#include "includes.h" +#include "nterr.h" + +extern int DEBUGLEVEL; + +#define DEBUG_TESTING + +extern struct cli_state *smb_cli; +extern int smb_tidx; + +extern FILE* out_hnd; + + +/**************************************************************************** +server get info query +****************************************************************************/ +void cmd_srv_query_info(struct client_info *info) +{ + fstring dest_srv; + fstring tmp; + SRV_INFO_CTR ctr; + uint32 info_level = 101; + + BOOL res = True; + + bzero(&ctr, sizeof(ctr)); + + strcpy(dest_srv, "\\\\"); + strcat(dest_srv, info->dest_host); + strupper(dest_srv); + + if (next_token(NULL, tmp, NULL)) + { + info_level = strtoul(tmp, (char**)NULL, 10); + } + + DEBUG(4,("cmd_srv_query_info: server:%s info level: %D\n", + dest_srv, info_level)); + + DEBUG(5, ("cmd_srv_query_info: smb_cli->fd:%d\n", smb_cli->fd)); + + /* open LSARPC session. */ + res = res ? do_session_open(smb_cli, smb_tidx, PIPE_SRVSVC, &(info->dom.srvsvc_fnum)) : False; + + /* send info level: receive requested info. hopefully. */ + res = res ? do_srv_net_srv_get_info(smb_cli, smb_tidx, info->dom.srvsvc_fnum, + dest_srv, info_level, &ctr) : False; + + /* close the session */ + do_session_close(smb_cli, smb_tidx, info->dom.srvsvc_fnum); + + if (res) + { + DEBUG(5,("cmd_srv_query_info: query succeeded\n")); + + display_srv_info_ctr(out_hnd, DISPLAY_TXT, ACTION_HEADER , &ctr); + display_srv_info_ctr(out_hnd, DISPLAY_TXT, ACTION_ENUMERATE, &ctr); + display_srv_info_ctr(out_hnd, DISPLAY_TXT, ACTION_FOOTER , &ctr); + } + else + { + DEBUG(5,("cmd_srv_query_info: query failed\n")); + } +} + +/**************************************************************************** +server enum connections +****************************************************************************/ +void cmd_srv_enum_conn(struct client_info *info) +{ + fstring dest_srv; + fstring qual_srv; + fstring tmp; + SRV_CONN_INFO_CTR ctr; + ENUM_HND hnd; + uint32 info_level = 0; + + BOOL res = True; + + bzero(&ctr, sizeof(ctr)); + + strcpy(qual_srv, "\\\\"); + strcat(qual_srv, info->myhostname); + strupper(qual_srv); + + strcpy(dest_srv, "\\\\"); + strcat(dest_srv, info->dest_host); + strupper(dest_srv); + + if (next_token(NULL, tmp, NULL)) + { + info_level = strtoul(tmp, (char**)NULL, 10); + } + + DEBUG(4,("cmd_srv_enum_conn: server:%s info level: %D\n", + dest_srv, info_level)); + + DEBUG(5, ("cmd_srv_enum_conn: smb_cli->fd:%d\n", smb_cli->fd)); + + /* open srvsvc session. */ + res = res ? do_session_open(smb_cli, smb_tidx, PIPE_SRVSVC, &(info->dom.srvsvc_fnum)) : False; + + hnd.ptr_hnd = 1; + hnd.handle = 0; + + /* enumerate connections on server */ + res = res ? do_srv_net_srv_conn_enum(smb_cli, smb_tidx, info->dom.srvsvc_fnum, + dest_srv, qual_srv, + info_level, &ctr, 0xffffffff, &hnd) : False; + + if (res) + { + display_srv_conn_info_ctr(out_hnd, DISPLAY_TXT, ACTION_HEADER , &ctr); + display_srv_conn_info_ctr(out_hnd, DISPLAY_TXT, ACTION_ENUMERATE, &ctr); + display_srv_conn_info_ctr(out_hnd, DISPLAY_TXT, ACTION_FOOTER , &ctr); + } + + /* close the session */ + do_session_close(smb_cli, smb_tidx, info->dom.srvsvc_fnum); + + if (res) + { + DEBUG(5,("cmd_srv_enum_conn: query succeeded\n")); + } + else + { + DEBUG(5,("cmd_srv_enum_conn: query failed\n")); + } +} + +/**************************************************************************** +server enum shares +****************************************************************************/ +void cmd_srv_enum_shares(struct client_info *info) +{ + fstring dest_srv; + fstring tmp; + SRV_SHARE_INFO_CTR ctr; + ENUM_HND hnd; + uint32 info_level = 1; + + BOOL res = True; + + bzero(&ctr, sizeof(ctr)); + + strcpy(dest_srv, "\\\\"); + strcat(dest_srv, info->dest_host); + strupper(dest_srv); + + if (next_token(NULL, tmp, NULL)) + { + info_level = strtoul(tmp, (char**)NULL, 10); + } + + DEBUG(4,("cmd_srv_enum_shares: server:%s info level: %D\n", + dest_srv, info_level)); + + DEBUG(5, ("cmd_srv_enum_shares: smb_cli->fd:%d\n", smb_cli->fd)); + + /* open srvsvc session. */ + res = res ? do_session_open(smb_cli, smb_tidx, PIPE_SRVSVC, &(info->dom.srvsvc_fnum)) : False; + + hnd.ptr_hnd = 0; + hnd.handle = 0; + + /* enumerate shares_files on server */ + res = res ? do_srv_net_srv_share_enum(smb_cli, smb_tidx, info->dom.srvsvc_fnum, + dest_srv, + info_level, &ctr, 0xffffffff, &hnd) : False; + + if (res) + { + display_srv_share_info_ctr(out_hnd, DISPLAY_TXT, ACTION_HEADER , &ctr); + display_srv_share_info_ctr(out_hnd, DISPLAY_TXT, ACTION_ENUMERATE, &ctr); + display_srv_share_info_ctr(out_hnd, DISPLAY_TXT, ACTION_FOOTER , &ctr); + } + + /* close the session */ + do_session_close(smb_cli, smb_tidx, info->dom.srvsvc_fnum); + + if (res) + { + DEBUG(5,("cmd_srv_enum_shares: query succeeded\n")); + } + else + { + DEBUG(5,("cmd_srv_enum_shares: query failed\n")); + } +} + +/**************************************************************************** +server enum sessions +****************************************************************************/ +void cmd_srv_enum_sess(struct client_info *info) +{ + fstring dest_srv; + fstring tmp; + SRV_SESS_INFO_CTR ctr; + ENUM_HND hnd; + uint32 info_level = 0; + + BOOL res = True; + + bzero(&ctr, sizeof(ctr)); + + strcpy(dest_srv, "\\\\"); + strcat(dest_srv, info->dest_host); + strupper(dest_srv); + + if (next_token(NULL, tmp, NULL)) + { + info_level = strtoul(tmp, (char**)NULL, 10); + } + + DEBUG(4,("cmd_srv_enum_sess: server:%s info level: %D\n", + dest_srv, info_level)); + + DEBUG(5, ("cmd_srv_enum_sess: smb_cli->fd:%d\n", smb_cli->fd)); + + /* open srvsvc session. */ + res = res ? do_session_open(smb_cli, smb_tidx, PIPE_SRVSVC, &(info->dom.srvsvc_fnum)) : False; + + hnd.ptr_hnd = 1; + hnd.handle = 0; + + /* enumerate sessions on server */ + res = res ? do_srv_net_srv_sess_enum(smb_cli, smb_tidx, info->dom.srvsvc_fnum, + dest_srv, NULL, info_level, &ctr, 0x1000, &hnd) : False; + + /* close the session */ + do_session_close(smb_cli, smb_tidx, info->dom.srvsvc_fnum); + + if (res) + { + DEBUG(5,("cmd_srv_enum_sess: query succeeded\n")); + } + else + { + DEBUG(5,("cmd_srv_enum_sess: query failed\n")); + } +} + +/**************************************************************************** +server enum files +****************************************************************************/ +void cmd_srv_enum_files(struct client_info *info) +{ + fstring dest_srv; + fstring tmp; + SRV_FILE_INFO_CTR ctr; + ENUM_HND hnd; + uint32 info_level = 3; + + BOOL res = True; + + bzero(&ctr, sizeof(ctr)); + + strcpy(dest_srv, "\\\\"); + strcat(dest_srv, info->dest_host); + strupper(dest_srv); + + if (next_token(NULL, tmp, NULL)) + { + info_level = strtoul(tmp, (char**)NULL, 10); + } + + DEBUG(4,("cmd_srv_enum_files: server:%s info level: %D\n", + dest_srv, info_level)); + + DEBUG(5, ("cmd_srv_enum_files: smb_cli->fd:%d\n", smb_cli->fd)); + + /* open srvsvc session. */ + res = res ? do_session_open(smb_cli, smb_tidx, PIPE_SRVSVC, &(info->dom.srvsvc_fnum)) : False; + + hnd.ptr_hnd = 1; + hnd.handle = 0; + + /* enumerate files on server */ + res = res ? do_srv_net_srv_file_enum(smb_cli, smb_tidx, info->dom.srvsvc_fnum, + dest_srv, NULL, info_level, &ctr, 0x1000, &hnd) : False; + + if (res) + { + display_srv_file_info_ctr(out_hnd, DISPLAY_TXT, ACTION_HEADER , &ctr); + display_srv_file_info_ctr(out_hnd, DISPLAY_TXT, ACTION_ENUMERATE, &ctr); + display_srv_file_info_ctr(out_hnd, DISPLAY_TXT, ACTION_FOOTER , &ctr); + } + + /* close the session */ + do_session_close(smb_cli, smb_tidx, info->dom.srvsvc_fnum); + + if (res) + { + DEBUG(5,("cmd_srv_enum_files: query succeeded\n")); + } + else + { + DEBUG(5,("cmd_srv_enum_files: query failed\n")); + } +} + diff --git a/source3/rpcclient/cmd_wkssvc.c b/source3/rpcclient/cmd_wkssvc.c new file mode 100644 index 0000000000..99524cba77 --- /dev/null +++ b/source3/rpcclient/cmd_wkssvc.c @@ -0,0 +1,96 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + NT Domain Authentication SMB / MSRPC client + Copyright (C) Andrew Tridgell 1994-1997 + Copyright (C) Luke Kenneth Casson Leighton 1996-1997 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + + +#ifdef SYSLOG +#undef SYSLOG +#endif + +#include "includes.h" +#include "nterr.h" + +extern int DEBUGLEVEL; + +#define DEBUG_TESTING + +extern struct cli_state *smb_cli; +extern int smb_tidx; + +extern FILE* out_hnd; + + +/**************************************************************************** +workstation get info query +****************************************************************************/ +void cmd_wks_query_info(struct client_info *info) +{ + fstring dest_wks; + fstring tmp; + WKS_INFO_100 ctr; + uint32 info_level = 100; + + BOOL res = True; + + bzero(&ctr, sizeof(ctr)); + + strcpy(dest_wks, "\\\\"); + strcat(dest_wks, info->dest_host); + strupper(dest_wks); + + if (next_token(NULL, tmp, NULL)) + { + info_level = strtoul(tmp, (char**)NULL, 10); + } + + DEBUG(4,("cmd_wks_query_info: server:%s info level: %D\n", + dest_wks, info_level)); + + DEBUG(5, ("cmd_wks_query_info: smb_cli->fd:%d\n", smb_cli->fd)); + + /* open LSARPC session. */ + res = res ? do_session_open(smb_cli, smb_tidx, PIPE_WKSSVC, &(info->dom.wkssvc_fnum)) : False; + + /* send info level: receive requested info. hopefully. */ + res = res ? do_wks_query_info(smb_cli, smb_tidx, info->dom.wkssvc_fnum, + dest_wks, info_level, &ctr) : False; + + /* close the session */ + do_session_close(smb_cli, smb_tidx, info->dom.wkssvc_fnum); + + if (res) + { + DEBUG(5,("cmd_wks_query_info: query succeeded\n")); + +#if 0 + display_wks_info_100(out_hnd, DISPLAY_TXT, ACTION_HEADER , &ctr); + display_wks_info_100(out_hnd, DISPLAY_TXT, ACTION_ENUMERATE, &ctr); + display_wks_info_100(out_hnd, DISPLAY_TXT, ACTION_FOOTER , &ctr); +#endif + + } + else + { + DEBUG(5,("cmd_wks_query_info: query failed\n")); + } +} + diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c new file mode 100644 index 0000000000..9c7d6f8305 --- /dev/null +++ b/source3/rpcclient/rpcclient.c @@ -0,0 +1,770 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + SMB client + Copyright (C) Andrew Tridgell 1994-1998 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef SYSLOG +#undef SYSLOG +#endif + +#include "includes.h" + +#ifndef REGISTER +#define REGISTER 0 +#endif + +extern pstring scope; + +extern pstring user_socket_options; + + +extern pstring debugf; +extern int DEBUGLEVEL; + + +extern file_info def_finfo; + +#define CNV_LANG(s) dos2unix_format(s,False) +#define CNV_INPUT(s) unix2dos_format(s,True) + +static int process_tok(fstring tok); +static void cmd_help(struct client_info *info); +static void cmd_quit(struct client_info *info); + +static struct cli_state smbcli; +struct cli_state *smb_cli = &smbcli; + +FILE *out_hnd = stdout; + +/**************************************************************************** +initialise smb client structure +****************************************************************************/ +void rpcclient_init(void) +{ + bzero(smb_cli, sizeof(smb_cli)); + cli_initialise(smb_cli); +} + +/**************************************************************************** +make smb client connection +****************************************************************************/ +static BOOL rpcclient_connect(struct client_info *info) +{ + struct nmb_name calling; + struct nmb_name called; + + make_nmb_name(&called , dns_to_netbios_name(info->dest_host ), info->name_type, scope); + make_nmb_name(&calling, dns_to_netbios_name(info->myhostname), 0x0 , scope); + + if (!cli_establish_connection(smb_cli, + info->dest_host, &info->dest_ip, + &calling, &called, + info->share, info->svc_type, + False, True)) + { + DEBUG(0,("rpcclient_connect: connection failed\n")); + cli_shutdown(smb_cli); + return False; + } + + return True; +} + +/**************************************************************************** +stop the smb connection(s?) +****************************************************************************/ +static void rpcclient_stop(void) +{ + cli_shutdown(smb_cli); +} +/**************************************************************************** + This defines the commands supported by this client + ****************************************************************************/ +struct +{ + char *name; + void (*fn)(struct client_info*); + char *description; +} commands[] = +{ +#if 0 + {"ntlogin", cmd_netlogon_login_test, " NT Domain login test"}, + {"wksinfo", cmd_wks_query_info, "DCE/RPC - Workstation Query Info"}, + {"srvinfo", cmd_srv_query_info, "DCE/RPC - Server Query Info"}, + {"srvsessions",cmd_srv_enum_sess, "DCE/RPC - List sessions on a server"}, + {"srvshares", cmd_srv_enum_shares, "DCE/RPC - List shares on a server"}, + {"srvconnections",cmd_srv_enum_conn, "DCE/RPC - List connections on a server"}, + {"srvfiles", cmd_srv_enum_files, "DCE/RPC - List files on a server"}, +#endif + {"lsaquery", cmd_lsa_query_info, "Query Info Policy (domain member or server)"}, +#if 0 + {"enumusers", cmd_sam_enum_users, "SAM User Database Query (experimental!)"}, + {"samuser", cmd_sam_query_user, " SAM User Query (experimental!)"}, + {"samtest", cmd_sam_test , "SAM User Encrypted RPC test (experimental!)"}, + {"enumaliases",cmd_sam_enum_aliases, "SAM Aliases Database Query (experimental!)"}, +#endif +#if 0 + {"enumgroups", cmd_sam_enum_groups, "SAM Group Database Query (experimental!)"}, +#endif +#if 0 + {"samgroups", cmd_sam_query_groups, "SAM Group Database Query (experimental!)"}, +#endif + {"quit", cmd_quit, "logoff the server"}, + {"q", cmd_quit, "logoff the server"}, + {"exit", cmd_quit, "logoff the server"}, + {"bye", cmd_quit, "logoff the server"}, + {"help", cmd_help, "[command] give help on a command"}, + {"?", cmd_help, "[command] give help on a command"}, + {"!", NULL, "run a shell command on the local system"}, + {"", NULL, NULL} +}; + + +/**************************************************************************** +do a (presumably graceful) quit... +****************************************************************************/ +static void cmd_quit(struct client_info *info) +{ + rpcclient_stop(); +#ifdef MEM_MAN + { + extern FILE* dbf; + smb_mem_write_status(dbf); + smb_mem_write_errors(dbf); + smb_mem_write_verbose(dbf); + } +#endif + exit(0); +} + +/**************************************************************************** +help +****************************************************************************/ +static void cmd_help(struct client_info *info) +{ + int i=0,j; + fstring buf; + + if (next_token(NULL,buf,NULL, sizeof(buf))) + { + if ((i = process_tok(buf)) >= 0) + fprintf(out_hnd, "HELP %s:\n\t%s\n\n",commands[i].name,commands[i].description); + } + else + while (commands[i].description) + { + for (j=0; commands[i].description && (j<5); j++) { + fprintf(out_hnd, "%-15s",commands[i].name); + i++; + } + fprintf(out_hnd, "\n"); + } +} + +/******************************************************************* + lookup a command string in the list of commands, including + abbreviations + ******************************************************************/ +static int process_tok(fstring tok) +{ + int i = 0, matches = 0; + int cmd=0; + int tok_len = strlen(tok); + + while (commands[i].fn != NULL) + { + if (strequal(commands[i].name,tok)) + { + matches = 1; + cmd = i; + break; + } + else if (strnequal(commands[i].name, tok, tok_len)) + { + matches++; + cmd = i; + } + i++; + } + + if (matches == 0) + return(-1); + else if (matches == 1) + return(cmd); + else + return(-2); +} + +/**************************************************************************** +wait for keyboard activity, swallowing network packets +****************************************************************************/ +static void wait_keyboard(struct cli_state *cli) +{ + fd_set fds; + int selrtn; + struct timeval timeout; + + while (1) + { + FD_ZERO(&fds); + FD_SET(cli->fd,&fds); + FD_SET(fileno(stdin),&fds); + + timeout.tv_sec = 20; + timeout.tv_usec = 0; + selrtn = sys_select(MAX(cli->fd,fileno(stdin))+1,&fds,&timeout); + + if (FD_ISSET(fileno(stdin),&fds)) + return; + + /* We deliberately use receive_smb instead of + client_receive_smb as we want to receive + session keepalives and then drop them here. + */ + if (FD_ISSET(cli->fd,&fds)) + receive_smb(cli->fd,cli->inbuf,0); + } +} + +/**************************************************************************** + process commands from the client +****************************************************************************/ +static void do_command(struct client_info *info, char *tok, char *line) +{ + int i; + + if ((i = process_tok(tok)) >= 0) + { + commands[i].fn(info); + } + else if (i == -2) + { + fprintf(out_hnd, "%s: command abbreviation ambiguous\n", CNV_LANG(tok)); + } + else + { + fprintf(out_hnd, "%s: command not found\n", CNV_LANG(tok)); + } +} + +/**************************************************************************** + process commands from the client +****************************************************************************/ +static BOOL process( struct client_info *info, char *cmd_str) +{ + extern FILE *dbf; + pstring line; + char *cmd = cmd_str; + + if (cmd[0] != '\0') while (cmd[0] != '\0') + { + char *p; + fstring tok; + + if ((p = strchr(cmd, ';')) == 0) + { + strncpy(line, cmd, 999); + line[1000] = '\0'; + cmd += strlen(cmd); + } + else + { + if (p - cmd > 999) p = cmd + 999; + strncpy(line, cmd, p - cmd); + line[p - cmd] = '\0'; + cmd = p + 1; + } + + /* input language code to internal one */ + CNV_INPUT (line); + + /* get the first part of the command */ + { + char *ptr = line; + if (!next_token(&ptr,tok,NULL, sizeof(tok))) continue; + } + + do_command(info, tok, line); + } + else while (!feof(stdin)) + { + fstring tok; + + /* display a prompt */ + fprintf(out_hnd, "smb: %s> ", CNV_LANG(info->cur_dir)); + fflush(out_hnd); + +#ifdef CLIX + line[0] = wait_keyboard(smb_cli); + /* this might not be such a good idea... */ + if ( line[0] == EOF) + { + break; + } +#else + wait_keyboard(smb_cli); +#endif + + /* and get a response */ +#ifdef CLIX + fgets( &line[1],999, stdin); +#else + if (!fgets(line,1000,stdin)) + { + break; + } +#endif + + /* input language code to internal one */ + CNV_INPUT (line); + + /* special case - first char is ! */ + if (*line == '!') + { + system(line + 1); + continue; + } + + fprintf(out_hnd, "%s\n", line); + + /* get the first part of the command */ + { + char *ptr = line; + if (!next_token(&ptr,tok,NULL, sizeof(tok))) continue; + } + + do_command(info, tok, line); + } + + return(True); +} + +/**************************************************************************** +usage on the program +****************************************************************************/ +static void usage(char *pname) +{ + fprintf(out_hnd, "Usage: %s service [-p port] [-d debuglevel] [-l log] ", + pname); + + fprintf(out_hnd, "\nVersion %s\n",VERSION); + fprintf(out_hnd, "\t-p port connect to the specified port\n"); + fprintf(out_hnd, "\t-d debuglevel set the debuglevel\n"); + fprintf(out_hnd, "\t-l log basename. Basename for log/debug files\n"); + fprintf(out_hnd, "\t-n netbios name. Use this name as my netbios name\n"); + fprintf(out_hnd, "\t-N don't ask for a password\n"); + fprintf(out_hnd, "\t-m max protocol set the max protocol level\n"); + fprintf(out_hnd, "\t-I dest IP use this IP to connect to\n"); + fprintf(out_hnd, "\t-E write messages to stderr instead of stdout\n"); + fprintf(out_hnd, "\t-U username set the network username\n"); + fprintf(out_hnd, "\t-W workgroup set the workgroup name\n"); + fprintf(out_hnd, "\t-c command string execute semicolon separated commands\n"); + fprintf(out_hnd, "\t-t terminal code terminal i/o code {sjis|euc|jis7|jis8|junet|hex}\n"); + fprintf(out_hnd, "\n"); +} + +enum client_action +{ + CLIENT_NONE, + CLIENT_IPC, + CLIENT_SVC +}; + +/**************************************************************************** + main program +****************************************************************************/ + int main(int argc,char *argv[]) +{ + char *pname = argv[0]; + int port = SMB_PORT; + int opt; + extern FILE *dbf; + extern char *optarg; + extern int optind; + static pstring servicesf = CONFIGFILE; + pstring term_code; + char *p; + BOOL got_pass = False; + char *cmd_str=""; + int myumask = 0755; + enum client_action cli_action = CLIENT_NONE; + int ret = 0; + + struct client_info cli_info; + + pstring password; /* local copy only, if one is entered */ + pstring tmp; + + rpcclient_init(); + +#ifdef KANJI + pstrcpy(term_code, KANJI); +#else /* KANJI */ + *term_code = 0; +#endif /* KANJI */ + + DEBUGLEVEL = 2; + + cli_info.put_total_size = 0; + cli_info.put_total_time_ms = 0; + cli_info.get_total_size = 0; + cli_info.get_total_time_ms = 0; + + cli_info.dir_total = 0; + cli_info.newer_than = 0; + cli_info.archive_level = 0; + cli_info.print_mode = 1; + + cli_info.translation = False; + cli_info.recurse_dir = False; + cli_info.lowercase = False; + cli_info.prompt = True; + cli_info.abort_mget = True; + + cli_info.dest_ip.s_addr = 0; + cli_info.name_type = 0x20; + + pstrcpy(cli_info.cur_dir , "\\"); + pstrcpy(cli_info.file_sel, ""); + pstrcpy(cli_info.base_dir, ""); + pstrcpy(smb_cli->domain, ""); + pstrcpy(smb_cli->user_name, ""); + pstrcpy(cli_info.myhostname, ""); + pstrcpy(cli_info.dest_host, ""); + + pstrcpy(cli_info.svc_type, "A:"); + pstrcpy(cli_info.share, ""); + pstrcpy(cli_info.service, ""); + + pstrcpy(cli_info.dom.level3_sid, ""); + pstrcpy(cli_info.dom.level3_dom, ""); + pstrcpy(cli_info.dom.level5_sid, ""); + pstrcpy(cli_info.dom.level5_dom, ""); + + smb_cli->nt_pipe_fnum = 0xffff; + + setup_logging(pname, True); + + TimeInit(); + charset_initialise(); + + myumask = umask(0); + umask(myumask); + + if (getenv("USER")) + { + pstrcpy(smb_cli->user_name,getenv("USER")); + + /* modification to support userid%passwd syntax in the USER var + 25.Aug.97, jdblair@uab.edu */ + + if ((p=strchr(smb_cli->user_name,'%'))) + { + *p = 0; + pstrcpy(password,p+1); + got_pass = True; + memset(strchr(getenv("USER"),'%')+1,'X',strlen(password)); + } + strupper(smb_cli->user_name); + } + + password[0] = 0; + + /* modification to support PASSWD environmental var + 25.Aug.97, jdblair@uab.edu */ + if (getenv("PASSWD")) + { + pstrcpy(password,getenv("PASSWD")); + } + + if (*smb_cli->user_name == 0 && getenv("LOGNAME")) + { + pstrcpy(smb_cli->user_name,getenv("LOGNAME")); + strupper(smb_cli->user_name); + } + + if (argc < 2) + { + usage(pname); + exit(1); + } + + if (*argv[1] != '-') + { + + pstrcpy(cli_info.service, argv[1]); + /* Convert any '/' characters in the service name to '\' characters */ + string_replace( cli_info.service, '/','\\'); + argc--; + argv++; + + DEBUG(1,("service: %s\n", cli_info.service)); + + if (count_chars(cli_info.service,'\\') < 3) + { + usage(pname); + printf("\n%s: Not enough '\\' characters in service\n", cli_info.service); + exit(1); + } + + /* + if (count_chars(cli_info.service,'\\') > 3) + { + usage(pname); + printf("\n%s: Too many '\\' characters in service\n", cli_info.service); + exit(1); + } + */ + + if (argc > 1 && (*argv[1] != '-')) + { + got_pass = True; + pstrcpy(password,argv[1]); + memset(argv[1],'X',strlen(argv[1])); + argc--; + argv++; + } + + cli_action = CLIENT_SVC; + } + + while ((opt = getopt(argc, argv,"s:B:O:M:S:i:N:d:Pp:l:hI:EB:U:L:t:m:W:T:D:c:")) != EOF) + { + switch (opt) + { + case 'm': + { + int max_protocol = interpret_protocol(optarg,max_protocol); + fprintf(stderr, "max protocol not currently supported\n"); + break; + } + + case 'O': + { + pstrcpy(user_socket_options,optarg); + break; + } + + case 'S': + { + pstrcpy(cli_info.dest_host,optarg); + strupper(cli_info.dest_host); + cli_action = CLIENT_IPC; + break; + } + + case 'B': + { + iface_set_default(NULL,optarg,NULL); + break; + } + + case 'i': + { + pstrcpy(scope, optarg); + break; + } + + case 'U': + { + char *lp; + pstrcpy(smb_cli->user_name,optarg); + if ((lp=strchr(smb_cli->user_name,'%'))) + { + *lp = 0; + pstrcpy(password,lp+1); + got_pass = True; + memset(strchr(optarg,'%')+1,'X',strlen(password)); + } + break; + } + + case 'W': + { + pstrcpy(smb_cli->domain,optarg); + break; + } + + case 'E': + { + dbf = stderr; + break; + } + + case 'I': + { + cli_info.dest_ip = *interpret_addr2(optarg); + if (zero_ip(cli_info.dest_ip)) + { + exit(1); + } + break; + } + + case 'N': + { + got_pass = True; + break; + } + + case 'd': + { + if (*optarg == 'A') + DEBUGLEVEL = 10000; + else + DEBUGLEVEL = atoi(optarg); + break; + } + + case 'l': + { + slprintf(debugf, sizeof(debugf)-1, + "%s.client",optarg); + break; + } + + case 'p': + { + port = atoi(optarg); + break; + } + + case 'c': + { + cmd_str = optarg; + got_pass = True; + break; + } + + case 'h': + { + usage(pname); + exit(0); + break; + } + + case 's': + { + pstrcpy(servicesf, optarg); + break; + } + + case 't': + { + pstrcpy(term_code, optarg); + break; + } + + default: + { + usage(pname); + exit(1); + break; + } + } + } + + if (cli_action == CLIENT_NONE) + { + usage(pname); + exit(1); + } + + DEBUG(3,("%s client started (version %s)\n",timestring(),VERSION)); + + if (!get_myname(cli_info.myhostname, NULL)) + { + fprintf(stderr, "Failed to get my hostname.\n"); + } + + if (!lp_load(servicesf,True, False, False)) + { + fprintf(stderr, "Can't load %s - run testparm to debug it\n", servicesf); + } + + codepage_initialise(lp_client_code_page()); + + if (*smb_cli->domain == 0) pstrcpy(smb_cli->domain,lp_workgroup()); + + load_interfaces(); + + if (cli_action == CLIENT_IPC) + { + pstrcpy(cli_info.share, "IPC$"); + pstrcpy(cli_info.svc_type, "IPC"); + } + + fstrcpy(cli_info.mach_acct, cli_info.myhostname); + strupper(cli_info.mach_acct); + fstrcat(cli_info.mach_acct, "$"); + + /* set the password cache info */ + if (got_pass) + { + if (password[0] == 0) + { + pwd_set_nullpwd(&(smb_cli->pwd)); + } + else + { + pwd_make_lm_nt_16(&(smb_cli->pwd), password); /* generate 16 byte hashes */ + } + } + else + { + pwd_read(&(smb_cli->pwd), "Enter Password:", True); + } + + /* paranoia: destroy the local copy of the password */ + bzero(password, sizeof(password)); + + /* establish connections. nothing to stop these being re-established. */ + rpcclient_connect(&cli_info); + + DEBUG(5,("rpcclient_connect: smb_cli->fd:%d\n", smb_cli->fd)); + if (smb_cli->fd <= 0) + { + fprintf(stderr, "warning: connection could not be established to %s<%02x>\n", + cli_info.dest_host, cli_info.name_type); + fprintf(stderr, "this version of smbclient may crash if you proceed\n"); + exit(-1); + } + + ret = 0; + + switch (cli_action) + { + case CLIENT_IPC: + { + ret = process(&cli_info, cmd_str) ? 0 : 1; + break; + } + + default: + { + fprintf(stderr, "unknown client action requested\n"); + ret = 1; + break; + } + } + + rpcclient_stop(); + + return(0); +} diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 1d90af3066..75934ec294 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -29,6 +29,7 @@ BOOL global_machine_pasword_needs_changing; /* users from session setup */ static pstring session_users=""; +extern pstring scope; extern pstring global_myname; extern fstring global_myworkgroup; @@ -929,6 +930,7 @@ struct cli_state *server_cryptkey(void) extern fstring local_machine; char *p; BOOL connected_ok = False; + struct nmb_name calling, called; if (!cli_initialise(&pw_cli)) return NULL; @@ -961,7 +963,11 @@ struct cli_state *server_cryptkey(void) return NULL; } - if (!cli_session_request(&pw_cli, desthost, 0x20, local_machine)) { + make_nmb_name(&calling, local_machine, 0x0 , scope); + make_nmb_name(&called , desthost , 0x20, scope); + + if (!cli_session_request(&pw_cli, &calling, &called)) + { DEBUG(1,("%s rejected the session\n",desthost)); cli_shutdown(&pw_cli); return NULL; @@ -1124,6 +1130,7 @@ BOOL domain_client_validate( char *user, char *domain, struct cli_state cli; uint32 smb_uid_low; BOOL connected_ok = False; + struct nmb_name calling, called; /* * Check that the requested domain is not our own machine name. @@ -1236,7 +1243,11 @@ machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli) )); continue; } - if (!cli_session_request(&cli, remote_machine, 0x20, global_myname)) { + make_nmb_name(&calling, global_myname , 0x0 , scope); + make_nmb_name(&called , remote_machine, 0x20, scope); + + if (!cli_session_request(&pw_cli, &calling, &called)) + { DEBUG(0,("domain_client_validate: machine %s rejected the session setup. \ Error was : %s.\n", remote_machine, cli_errstr(&cli) )); cli_shutdown(&cli); diff --git a/source3/ubiqx/sys_include.h b/source3/ubiqx/sys_include.h index 00c4485aed..acfa5cdb84 100644 --- a/source3/ubiqx/sys_include.h +++ b/source3/ubiqx/sys_include.h @@ -38,8 +38,8 @@ * used before the headers that define them. These headers are not needed * in the ubiqx modules anyway. */ -#define _NAMESERV_H_ #define _PROTO_H_ +#define _NAMESERV_H_ /* The main Samba system-adaptive header file. */ diff --git a/source3/utils/smbpasswd.c b/source3/utils/smbpasswd.c index b97b0c765f..3ed3a11ba4 100644 --- a/source3/utils/smbpasswd.c +++ b/source3/utils/smbpasswd.c @@ -196,6 +196,8 @@ int main(int argc, char **argv) char *new_domain = NULL; pstring servicesf = CONFIGFILE; void *vp; + struct nmb_name calling, called; + new_passwd[0] = '\0'; user_name[0] = '\0'; @@ -493,7 +495,11 @@ int main(int argc, char **argv) exit(1); } - if (!cli_session_request(&cli, remote_machine, 0x20, global_myname)) { + make_nmb_name(&calling, global_myname , 0x0 , scope); + make_nmb_name(&called , remote_machine, 0x20, scope); + + if (!cli_session_request(&cli, &calling, &called)) + { fprintf(stderr, "%s: machine %s rejected the session setup. Error was : %s.\n", prog_name, remote_machine, cli_errstr(&cli) ); cli_shutdown(&cli); -- cgit