From bd529d7a83c35be233baca09bc79aa911ad443ce Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 6 Nov 1997 23:03:58 +0000 Subject: following a cvs error, i am rewriting this monster-commit. with bad grace. Modified Files: --------------- Makefile: adding extra files ipc.c : send_trans_reply() - alignment issue. this makes the alignment the same as that in NT. this should be looked at by people who understand the SMB stuff better than i. api_fd_commands[] - added samr and wkssvc pipes. loadparm.c : lp_domain_controller() changed to mean "samba is a domain controller". it's a "yes/no" parameter, now. no, it isn't used _anywhere_. namedbwork.c nameelect.c : if "domain controller = yes" then add SV_TYPE_DOMAIN_CTRL to the host _and_ workgroup announcements. yes, you must do both: nt does. namelogon.c : important NETLOGON bug in SAMLOGON request parsing, which may be the source of some people's problems with logging on to the Samba PDC. password.c : get_smbpwnam() renamed to get_smbpwd_entry(). pipes.c : added samr and wkssvc pipes. proto.h : usual. can we actually _remove_ proto.h from the cvs tree, and have it as one of the Makefile dependencies, or something? reply.c : get_smbpwnam() renamed to get_smbpwd_entry() - also changed response error code when logging in from a WORKSTATION$ account. yes, paul is right: we need to know when to return the right error code, and why. server.c : added call to reset_chain_pnum(). #ifdef NTDOMAIN added call to init_lsa_policy_hnd() #endif. jeremy, you'd be proud: i did a compile without NTDOMAIN, and caught a link error for this function. smb.h : defines and structures for samr and wkssvc pipes. smbpass.c : modified get_smbpwnam() to get_smbpwd_entry() and it now takes two arguments. one for the name; if this is null, it looks up by smb_userid instead. oh, by the way, smb_userids are actually domain relative ids (RIDs). concatenate a RID with the domain SID, and you have an internet globally unique way of identifying a user. we're using RIDs in the wrong way.... added mod_smbpwnam() function. this was based on code in smbpasswd.c rpc_pipes/lsaparse.c : added enum trusted domain parsing. this is incomplete: i need a packet trace to write it properly. rpc_pipes/pipe_hnd.c : added reset_chain_pnum() function. rpc_pipes/pipenetlog.c : get_smbpwnam() function renamed to get_smbpwd_entry(). arcfour() issues. removed capability of get_md4pw() function to automatically add workstation accounts. this should either be done using smbpasswd -add MACHINE$, or by using \PIPE\samr. rpc_pipes/pipe_util.c : create_pol_hnd() - creates a unique LSA Policy Handle. overkill function: uses a 64 bit sequence number; current unix time and the smbd pid. rpc_pipes/smbparse.c : arcfour() issues. smb_io_unistr2() should advance by uni_str_len not uni_max_len. smb_io_smb_hdr_rb() - request bind uses uint16 for the context id, and uint8 for the num_syntaxes. oops, i put these both as uint32s. Added Files: ------------ rpc_pipes/lsa_hnd.c : on the samr pipe, allocate and associate an LSA Policy Handle with a SID. you receive queries with the LSA Policy Handle, and have to turn this back into a SID in order to answer the query... rpc_pipes/pipesamr.c rpc_pipes/samrparse.c \PIPE\samr processing. samr i presume is the SAM Replication pipe. rpc_pipes/pipewkssvc.c rpc_pipes/wksparse.c \PIPE\wkssvc processing. the Workstation Service pipe? holy cow. (This used to be commit 1bd084b3e690eb26a1006d616075e53d711ecd2f) --- source3/include/proto.h | 61 ++++++- source3/include/smb.h | 314 ++++++++++++++++++++++++++------- source3/namedbwork.c | 7 +- source3/nameelect.c | 2 + source3/namelogon.c | 15 +- source3/param/loadparm.c | 6 +- source3/passdb/smbpass.c | 442 ++++++++++++++++++++++++++++++++++++++++++----- source3/smbd/ipc.c | 4 +- source3/smbd/password.c | 3 +- source3/smbd/pipes.c | 4 + source3/smbd/reply.c | 14 +- source3/smbd/server.c | 6 + 12 files changed, 755 insertions(+), 123 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 4054a12c19..5bb709858f 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -201,7 +201,6 @@ char *lp_passwd_program(void); char *lp_passwd_chat(void); char *lp_passwordserver(void); char *lp_workgroup(void); -char *lp_domain_controller(void); char *lp_username_map(void); char *lp_character_set(void); char *lp_logon_script(void); @@ -227,6 +226,7 @@ BOOL lp_dns_proxy(void); BOOL lp_wins_support(void); BOOL lp_wins_proxy(void); BOOL lp_local_master(void); +BOOL lp_domain_controller(void); BOOL lp_domain_master(void); BOOL lp_domain_logons(void); BOOL lp_preferred_master(void); @@ -763,6 +763,14 @@ int reply_writebs(char *inbuf,char *outbuf); int reply_setattrE(char *inbuf,char *outbuf); int reply_getattrE(char *inbuf,char *outbuf); +/*The following definitions come from rpc_pipes/lsa_hnd.c */ + +void init_lsa_policy_hnd(void); +BOOL open_lsa_policy_hnd(LSA_POL_HND *hnd, DOM_SID *sid); +BOOL set_lsa_policy_samr_rid(LSA_POL_HND *hnd, uint32 rid); +uint32 get_lsa_policy_samr_rid(LSA_POL_HND *hnd); +BOOL close_lsa_policy_hnd(LSA_POL_HND *hnd); + /*The following definitions come from rpc_pipes/lsaparse.c */ void make_q_open_pol(LSA_Q_OPEN_POL *r_q, char *server_name, @@ -772,6 +780,9 @@ char* lsa_io_q_open_pol(BOOL io, LSA_Q_OPEN_POL *r_q, char *q, char *base, int a char* lsa_io_r_open_pol(BOOL io, LSA_R_OPEN_POL *r_p, char *q, char *base, int align, int depth); void make_q_query(LSA_Q_QUERY_INFO *q_q, LSA_POL_HND *hnd, uint16 info_class); char* lsa_io_q_query(BOOL io, LSA_Q_QUERY_INFO *q_q, char *q, char *base, int align, int depth); +char* lsa_io_q_enum_trust_dom(BOOL io, LSA_Q_ENUM_TRUST_DOM *q_e, char *q, char *base, int align, int depth); +void make_r_enum_trust_dom(LSA_R_ENUM_TRUST_DOM *r_e, LSA_POL_HND *hnd, uint32 status); +char* lsa_io_r_enum_trust_dom(BOOL io, LSA_R_ENUM_TRUST_DOM *r_e, char *q, char *base, int align, int depth); void make_q_close(LSA_Q_CLOSE *q_c, LSA_POL_HND *hnd); char* lsa_io_q_close(BOOL io, LSA_Q_CLOSE *q_c, char *q, char *base, int align, int depth); void make_r_close(LSA_R_CLOSE *q_r, LSA_POL_HND *hnd); @@ -840,6 +851,7 @@ BOOL rpc_pipe_bind(char *pipe_name, uint16 fnum, uint32 call_id, /*The following definitions come from rpc_pipes/pipe_hnd.c */ +void reset_chain_pnum(void); void init_rpc_pipe_hnd(void); int open_rpc_pipe_hnd(char *pipe_name, int cnum); char *get_rpc_pipe_hnd_name(int pnum); @@ -861,6 +873,13 @@ BOOL api_ntLsarpcTNP(int cnum,int uid, char *param,char *data, char **rdata,char **rparam, int *rdata_len,int *rparam_len); +/*The following definitions come from rpc_pipes/pipesamr.c */ + +BOOL api_samrTNP(int cnum,int uid, char *param,char *data, + int mdrcnt,int mprcnt, + char **rdata,char **rparam, + int *rdata_len,int *rparam_len); + /*The following definitions come from rpc_pipes/pipesrvsvc.c */ BOOL api_srvsvcTNP(int cnum,int uid, char *param,char *data, @@ -870,6 +889,7 @@ BOOL api_srvsvcTNP(int cnum,int uid, char *param,char *data, /*The following definitions come from rpc_pipes/pipeutil.c */ +void create_pol_hnd(LSA_POL_HND *hnd); void initrpcreply(char *inbuf, char *q); void endrpcreply(char *inbuf, char *q, int datalen, int rtnval, int *rlen); BOOL name_to_rid(char *user_name, uint32 *u_rid, uint32 *g_rid); @@ -879,6 +899,35 @@ int make_dom_gids(char *gids_str, DOM_GID *gids); int create_rpc_request(uint32 call_id, uint8 op_num, char *q, int data_len); int create_rpc_reply(uint32 call_id, char *q, int data_len); +/*The following definitions come from rpc_pipes/pipewkssvc.c */ + +BOOL api_wkssvcTNP(int cnum,int uid, char *param,char *data, + int mdrcnt,int mprcnt, + char **rdata,char **rparam, + int *rdata_len,int *rparam_len); + +/*The following definitions come from rpc_pipes/samrparse.c */ + +char* samr_io_q_close(BOOL io, SAMR_Q_CLOSE *q_u, char *q, char *base, int align, int depth); +char* samr_io_r_close(BOOL io, SAMR_R_CLOSE *r_u, char *q, char *base, int align, int depth); +char* samr_io_q_open_secret(BOOL io, SAMR_Q_OPEN_SECRET *q_u, char *q, char *base, int align, int depth); +char* samr_io_r_open_secret(BOOL io, SAMR_R_OPEN_SECRET *r_u, char *q, char *base, int align, int depth); +char* samr_io_q_unknown_11(BOOL io, SAMR_Q_UNKNOWN_11 *q_u, char *q, char *base, int align, int depth); +void make_samr_r_unknown_11(SAMR_R_UNKNOWN_11 *r_u, + uint32 switch_value, uint32 unknown_0, uint32 status); +char* samr_io_r_unknown_11(BOOL io, SAMR_R_UNKNOWN_11 *r_u, char *q, char *base, int align, int depth); +char* samr_io_q_unknown_22(BOOL io, SAMR_Q_UNKNOWN_22 *q_u, char *q, char *base, int align, int depth); +char* samr_io_r_unknown_22(BOOL io, SAMR_R_UNKNOWN_22 *r_u, char *q, char *base, int align, int depth); +char* samr_io_q_unknown_24(BOOL io, SAMR_Q_UNKNOWN_24 *q_u, char *q, char *base, int align, int depth); +void make_samr_r_unknown_24(SAMR_R_UNKNOWN_24 *r_u, + uint16 unknown_0, NTTIME *expiry, char *mach_acct, + uint32 unknown_id_0, uint32 status); +char* samr_io_r_unknown_24(BOOL io, SAMR_R_UNKNOWN_24 *r_u, char *q, char *base, int align, int depth); +char* samr_io_q_unknown_32(BOOL io, SAMR_Q_UNKNOWN_32 *q_u, char *q, char *base, int align, int depth); +char* samr_io_r_unknown_32(BOOL io, SAMR_R_UNKNOWN_32 *r_u, char *q, char *base, int align, int depth); +char* samr_io_q_unknown_39(BOOL io, SAMR_Q_UNKNOWN_39 *q_u, char *q, char *base, int align, int depth); +char* samr_io_r_unknown_39(BOOL io, SAMR_R_UNKNOWN_39 *r_u, char *q, char *base, int align, int depth); + /*The following definitions come from rpc_pipes/smbparse.c */ char* smb_io_utime(BOOL io, UTIME *t, char *q, char *base, int align, int depth); @@ -969,6 +1018,11 @@ char* srv_io_share_1_ctr(BOOL io, SHARE_INFO_1_CTR *ctr, char *q, char *base, in char* srv_io_q_net_share_enum(BOOL io, SRV_Q_NET_SHARE_ENUM *q_n, char *q, char *base, int align, int depth); char* srv_io_r_net_share_enum(BOOL io, SRV_R_NET_SHARE_ENUM *r_n, char *q, char *base, int align, int depth); +/*The following definitions come from rpc_pipes/wksparse.c */ + +char* wks_io_q_unknown_0(BOOL io, WKS_Q_UNKNOWN_0 *q_u, char *q, char *base, int align, int depth); +char* wks_io_r_unknown_0(BOOL io, WKS_R_UNKNOWN_0 *r_u, char *q, char *base, int align, int depth); + /*The following definitions come from server.c */ void *dflt_sig(void); @@ -1051,8 +1105,9 @@ char *smb_errstr(char *inbuf); int pw_file_lock(char *name, int type, int secs); int pw_file_unlock(int fd); -struct smb_passwd *get_smbpwnam(char *name); -BOOL add_smbpwnam(struct smb_passwd* pwd); +struct smb_passwd *get_smbpwd_entry(char *name, int smb_userid); +BOOL add_smbpwd_entry(struct smb_passwd* pwd); +BOOL mod_smbpwd_entry(struct smb_passwd* pwd); /*The following definitions come from status.c */ diff --git a/source3/include/smb.h b/source3/include/smb.h index 892c31be97..83e1d9f85d 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -255,8 +255,11 @@ typedef fstring string; /* pipe strings */ #define PIPE_LANMAN "\\PIPE\\LANMAN" #define PIPE_SRVSVC "\\PIPE\\srvsvc" +#define PIPE_SAMR "\\PIPE\\samr" +#define PIPE_WKSSVC "\\PIPE\\wkssvc" #define PIPE_NETLOGON "\\PIPE\\NETLOGON" #define PIPE_NTLSA "\\PIPE\\ntlsa" +#define PIPE_NTSVCS "\\PIPE\\ntsvcs" #define PIPE_LSASS "\\PIPE\\lsass" #define PIPE_LSARPC "\\PIPE\\lsarpc" @@ -288,6 +291,15 @@ enum RPC_PKT_TYPE #define ACB_PWNOEXP /* 1 = User password does not expire */ #define ACB_AUTOLOCK /* 1 = Account auto locked */ +#define SAMR_CLOSE 0x01 +#define SAMR_OPEN_SECRET 0x07 +#define SAMR_LOOKUPNAMES 0x11 +#define SAMR_UNKNOWN_3 0x03 +#define SAMR_UNKNOWN_22 0x22 +#define SAMR_UNKNOWN_24 0x24 +#define SAMR_UNKNOWN_34 0x34 +#define SAMR_UNKNOWN_39 0x39 + #define LSA_OPENPOLICY 0x2c #define LSA_QUERYINFOPOLICY 0x07 #define LSA_ENUMTRUSTDOM 0x0d @@ -298,10 +310,12 @@ enum RPC_PKT_TYPE #define LSA_AUTH2 0x0f #define LSA_CLOSE 0x00 -/* XXXX these are just here to get a compile!!! */ +/* XXXX these are here to get a compile! */ + #define LSA_OPENSECRET 0xFF #define LSA_LOOKUPSIDS 0xFE -#define LSA_LOOKUPNAMES 0xFD +#define LSA_LOOKUPRIDS 0xFD +#define LSA_LOOKUPNAMES 0xFC /* srvsvc pipe */ #define NETSERVERGETINFO 0x15 @@ -716,6 +730,24 @@ typedef struct lsa_r_query_info } LSA_R_QUERY_INFO; +/* LSA_Q_ENUM_TRUST_DOM - LSA enumerate trusted domains */ +typedef struct lsa_enum_trust_dom_info +{ + LSA_POL_HND pol; /* policy handle */ + uint32 enum_context; /* enumeration context handle */ + uint32 preferred_len; /* preferred maximum length */ + +} LSA_Q_ENUM_TRUST_DOM; + +/* LSA_R_ENUM_TRUST_DOM - response to LSA enumerate trusted domains */ +typedef struct lsa_r_enum_trust_dom_info +{ + LSA_POL_HND pol; /* policy handle */ + + uint32 status; /* return code */ + +} LSA_R_ENUM_TRUST_DOM; + /* LSA_Q_CLOSE */ typedef struct lsa_q_close_info { @@ -1074,69 +1106,227 @@ typedef struct r_net_share_enum_info } SRV_R_NET_SHARE_ENUM; +/* SAMR_Q_CLOSE - probably a policy handle close */ +typedef struct q_samr_close_info +{ + LSA_POL_HND pol; /* policy handle */ + +} SAMR_Q_CLOSE; -/* -Yet to be turned into structures: - -6) \\MAILSLOT\NET\NTLOGON -------------------------- - -6.1) Query for PDC ------------------- - -Request: - - uint16 0x0007 - Query for PDC - STR machine name - STR response mailslot - uint8[] padding to 2-byte align with start of mailslot. - UNISTR machine name - uint32 NTversion - uint16 LMNTtoken - uint16 LM20token - -Response: - - uint16 0x000A - Respose to Query for PDC - STR machine name (in uppercase) - uint8[] padding to 2-byte align with start of mailslot. - UNISTR machine name - UNISTR domain name - uint32 NTversion (same as received in request) - uint16 LMNTtoken (same as received in request) - uint16 LM20token (same as received in request) - - -6.2) SAM Logon --------------- - -Request: - - uint16 0x0012 - SAM Logon - uint16 request count - UNISTR machine name - UNISTR user name - STR response mailslot - uint32 alloweable account - uint32 domain SID size - char[sid_size] domain SID, of sid_size bytes. - uint8[] ???? padding to 4? 2? -byte align with start of mailslot. - uint32 NTversion - uint16 LMNTtoken - uint16 LM20token - -Response: +/* SAMR_R_CLOSE - probably a policy handle close */ +typedef struct r_samr_close_info +{ + LSA_POL_HND pol; /* policy handle */ + uint32 status; /* return status */ - uint16 0x0013 - Response to SAM Logon - UNISTR machine name - UNISTR user name - workstation trust account - UNISTR domain name - uint32 NTversion - uint16 LMNTtoken - uint16 LM20token +} SAMR_R_CLOSE; -*/ + +/**************************************************************************** +SAMR_Q_OPEN_SECRET - unknown_0 values seen associated with SIDs: + +0x0000 0200 and a specific domain sid - S-1-5-21-44c01ca6-797e5c3d-33f83fd0 +0x0000 0280 and a well-known domain sid - S-1-5-20 +0x2000 0000 and a well-known domain sid - S-1-5-20 +0x2000 0000 and a specific domain sid - S-1-5-21-44c01ca6-797e5c3d-33f83fd0 +*****************************************************************************/ + +/* SAMR_Q_OPEN_SECRET - probably an open secret */ +typedef struct q_samr_open_secret_info +{ + LSA_POL_HND pol; /* policy handle */ + uint32 unknown_0; /* 0x2000 0000; 0x0000 0211; 0x0000 0280; 0x0000 0200 - unknown */ + DOM_SID dom_sid; /* domain SID */ + +} SAMR_Q_OPEN_SECRET; + + +/* SAMR_R_OPEN_SECRET - probably an open */ +typedef struct r_samr_open_secret_info +{ + LSA_POL_HND pol; /* policy handle associated with the SID */ + uint32 status; /* return status */ + +} SAMR_R_OPEN_SECRET; + + +/* SAMR_Q_UNKNOWN_11 - probably a "read SAM entry" */ +typedef struct q_samr_unknown_11_info +{ + LSA_POL_HND pol; /* policy handle */ + + uint32 switch_value1; /* 1 - switch value? */ + uint32 unknown_0; /* 0x0000 03E8 - 32 bit unknown */ + uint32 unknown_1; /* 0 - 32 bit unknown */ + uint32 switch_value2; /* 1 - switch value? */ + + UNIHDR hdr_mach_acct; /* unicode machine account name header */ + UNISTR2 uni_mach_acct; /* unicode machine account name */ + +} SAMR_Q_UNKNOWN_11; + + +/* SAMR_R_UNKNOWN_11 - probably an open */ +typedef struct r_samr_unknown_11_info +{ + uint32 switch_value1; /* 1 - switch value? */ + uint32 ptr_0; /* pointer */ + uint32 switch_value2; /* 1 - switch value? */ + uint32 unknown_0; /* 0x000003e8 - 32 bit unknown */ + uint32 switch_value3; /* 1 - switch value? */ + uint32 ptr_1; /* pointer */ + uint32 switch_value4; /* 1 - switch value? */ + uint32 switch_value5; /* 1 - switch value? */ + + uint32 status; /* return status - 0x99: user exists */ + +} SAMR_R_UNKNOWN_11; + + +/* SAMR_Q_UNKNOWN_22 - probably an open */ +typedef struct q_samr_unknown_22_info +{ + LSA_POL_HND pol; /* policy handle */ + uint32 unknown_id_0; /* 0x0000 03E8 - 32 bit unknown id */ + +} SAMR_Q_UNKNOWN_22; + + +/* SAMR_R_UNKNOWN_22 - probably an open */ +typedef struct r_samr_unknown_22_info +{ + LSA_POL_HND pol; /* policy handle associated with unknown id */ + uint32 status; /* return status */ + +} SAMR_R_UNKNOWN_22; + + +/* SAMR_Q_UNKNOWN_24 - probably a get sam info */ +typedef struct q_samr_unknown_24_info +{ + LSA_POL_HND pol; /* policy handle associated with unknown id */ + uint16 unknown_0; /* 0x0015 or 0x0011 - 16 bit unknown */ + +} SAMR_Q_UNKNOWN_24; + + +/* SAMR_R_UNKNOWN_24 - probably a get sam info */ +typedef struct r_samr_unknown_24_info +{ + uint32 ptr; /* pointer */ + uint16 unknown_0; /* 0x0015 or 0x0011 - 16 bit unknown (same as above) */ + uint16 unknown_1; /* 0x8b73 - 16 bit unknown */ + uint8 padding_0[16]; /* 0 - padding 16 bytes */ + NTTIME expiry; /* expiry time or something? */ + uint8 padding_1[24]; /* 0 - padding 24 bytes */ + + UNIHDR hdr_mach_acct; /* unicode header for machine account */ + uint32 padding_2; /* 0 - padding 4 bytes */ + + uint32 ptr_1; /* pointer */ + uint8 padding_3[32]; /* 0 - padding 32 bytes */ + uint32 padding_4; /* 0 - padding 4 bytes */ + + uint32 ptr_2; /* pointer */ + uint32 padding_5; /* 0 - padding 4 bytes */ + + uint32 ptr_3; /* pointer */ + uint8 padding_6[32]; /* 0 - padding 32 bytes */ + + uint32 unknown_id_0; /* unknown id associated with policy handle */ + uint16 unknown_2; /* 0x0201 - 16 bit unknown */ + uint32 unknown_3; /* 0x0000 0080 - 32 bit unknown */ + uint16 unknown_4; /* 0x003f - 16 bit unknown */ + uint16 unknown_5; /* 0x003c - 16 bit unknown */ + + uint8 padding_7[16]; /* 0 - padding 16 bytes */ + uint32 padding_8; /* 0 - padding 4 bytes */ + + UNISTR2 uni_mach_acct; /* unicode string for machine account */ + + uint8 padding_9[48]; /* 0 - padding 48 bytes */ + + uint32 status; /* return status */ + +} SAMR_R_UNKNOWN_24; + + +/* SAMR_Q_UNKNOWN_32 - probably a "create SAM entry" */ +typedef struct q_samr_unknown_32_info +{ + LSA_POL_HND pol; /* policy handle */ + + UNIHDR hdr_mach_acct; /* unicode machine account name header */ + UNISTR2 uni_mach_acct; /* unicode machine account name */ + + uint32 unknown_0; /* 32 bit unknown */ + uint16 unknown_1; /* 16 bit unknown */ + uint16 unknown_2; /* 16 bit unknown */ + +} SAMR_Q_UNKNOWN_32; + + +/* SAMR_R_UNKNOWN_32 - probably a "create SAM entry" */ +typedef struct r_samr_unknown_32_info +{ + LSA_POL_HND pol; /* policy handle */ + uint32 unknown_0; /* 0x0000 0030 - 32 bit unknown */ + uint32 padding; /* 0 - 4 byte padding */ + + uint32 status; /* return status - 0xC000 0099: user exists */ + +} SAMR_R_UNKNOWN_32; + + +/* SAMR_Q_UNKNOWN_39 - probably an open */ +typedef struct q_samr_unknown_39_info +{ + uint32 ptr_srv_name; /* pointer (to server name?) */ + UNISTR2 uni_srv_name; /* unicode server name starting with '\\' */ + + uint32 unknown_0; /* 32 bit unknown */ + +} SAMR_Q_UNKNOWN_39; + + +/* SAMR_R_UNKNOWN_39 - probably an open */ +typedef struct r_samr_unknown_39_info +{ + LSA_POL_HND pol; /* policy handle */ + uint32 status; /* return status */ + +} SAMR_R_UNKNOWN_39; + + +/* WKS_Q_UNKNOWN_0 - probably a capabilities request */ +typedef struct q_wks_unknown_0_info +{ + uint32 ptr_srv_name; /* pointer (to server name?) */ + UNISTR2 uni_srv_name; /* unicode server name starting with '\\' */ + + uint32 unknown_0; /* 0x64 - 32 bit unknown */ + uint16 unknown_1; /* 16 bit unknown */ + +} WKS_Q_UNKNOWN_0; + + +/* WKS_R_UNKNOWN_0 - probably a capabilities request */ +typedef struct r_wks_unknown_0_info +{ + uint32 unknown_0; /* 64 - unknown */ + uint32 ptr_1; /* pointer 1 */ + uint32 unknown_1; /* 0x0000 01f4 - unknown */ + uint32 ptr_srv_name; /* pointer to server name */ + uint32 ptr_dom_name; /* pointer to domain name */ + uint32 unknown_2; /* 4 - unknown */ + uint32 unknown_3; /* 0 - unknown */ + + UNISTR2 uni_srv_name; /* unicode server name */ + UNISTR2 uni_dom_name; /* unicode domainn name */ + uint32 status; /* return status */ + +} WKS_R_UNKNOWN_0; struct smb_passwd @@ -1148,7 +1338,6 @@ struct smb_passwd /* Other fields / flags may be added later */ }; - struct cli_state { int fd; int cnum; @@ -1175,6 +1364,7 @@ struct cli_state { int initialised; }; + struct current_user { int cnum, id; diff --git a/source3/namedbwork.c b/source3/namedbwork.c index a6260aab46..b01eb927e8 100644 --- a/source3/namedbwork.c +++ b/source3/namedbwork.c @@ -89,8 +89,11 @@ static struct work_record *make_workgroup(char *name) StrnCpy(work->work_group,name,sizeof(work->work_group)-1); work->serverlist = NULL; - work->ServerType = lp_default_server_announce() | (lp_local_master() ? - SV_TYPE_POTENTIAL_BROWSER : 0 ); + /* set up initial value for server announce type */ + work->ServerType = lp_default_server_announce(); + work->ServerType |= lp_local_master() ? SV_TYPE_POTENTIAL_BROWSER : 0; + work->ServerType |= lp_domain_controller() ? SV_TYPE_DOMAIN_CTRL : 0; + work->RunningElection = False; work->ElectionCount = 0; work->announce_interval = 0; diff --git a/source3/nameelect.c b/source3/nameelect.c index 391320e84f..ae4dc0857a 100644 --- a/source3/nameelect.c +++ b/source3/nameelect.c @@ -323,6 +323,8 @@ void become_local_master(struct subnet_record *d, struct work_record *work) */ uint32 domain_type = SV_TYPE_DOMAIN_ENUM|SV_TYPE_NT; + if (lp_domain_controller()) domain_type |= SV_TYPE_DOMAIN_CTRL; + if (!work || !d) return; diff --git a/source3/namelogon.c b/source3/namelogon.c index d8e0fcfc76..697a11a16a 100644 --- a/source3/namelogon.c +++ b/source3/namelogon.c @@ -118,12 +118,13 @@ void process_logon_packet(struct packet_struct *p,char *buf,int len) { char *q = buf + 2; char *machine = q; + mailslot = skip_string(machine,1); unicomp = skip_string(mailslot,1); - q = align2(q, buf); + q = align2(unicomp, buf); - q = skip_unicode_string(unicomp,1); + q = skip_unicode_string(q, 1); ntversion = IVAL(q, 0); q += 4; lmnttoken = SVAL(q, 0); q += 2; @@ -176,17 +177,21 @@ void process_logon_packet(struct packet_struct *p,char *buf,int len) ntversion = IVAL(q, 0); q += 4; lmnttoken = SVAL(q, 0); q += 2; lm20token = SVAL(q, 0); q += 2; + DEBUG(3,("SAMLOGON sidsize %d ntv %d\n", domainsidsize, ntversion)); /* If MACHINE$ is in our password database then respond, else ignore. Let's ignore the SID. */ - strcpy(ascuser,unistr(uniuser)); + + strcpy(ascuser, unistr(uniuser)); DEBUG(3,("SAMLOGON user %s\n", ascuser)); + strcpy(reply_name,"\\\\"); /* Here it wants \\LOGONSERVER */ - strcpy(reply_name+2,my_name); /* PAXX: Assuming we are logon svr */ - smb_pass = get_smbpwnam(ascuser); + strcpy(reply_name+2,my_name); + + smb_pass = get_smbpwd_entry(ascuser, 0); if(!smb_pass) { diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 2fe616f709..69c5fbd5c2 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -127,7 +127,6 @@ typedef struct char *szSocketOptions; char *szValidChars; char *szWorkGroup; - char *szDomainController; char *szDomainAdminUsers; char *szDomainGuestUsers; char *szDomainHostsallow; @@ -175,6 +174,7 @@ typedef struct BOOL bWINSproxy; BOOL bLocalMaster; BOOL bPreferredMaster; + BOOL bDomainController; BOOL bDomainMaster; BOOL bDomainLogons; BOOL bEncryptPasswords; @@ -454,7 +454,7 @@ struct parm_struct {"domain sid", P_USTRING, P_GLOBAL, &Globals.szDomainSID, NULL}, {"domain other sids",P_STRING, P_GLOBAL, &Globals.szDomainOtherSIDs, NULL}, {"domain groups", P_STRING, P_GLOBAL, &Globals.szDomainGroups, NULL}, - {"domain controller",P_STRING, P_GLOBAL, &Globals.szDomainController,NULL}, + {"domain controller",P_BOOL , P_GLOBAL, &Globals.bDomainController,NULL}, {"domain admin users",P_STRING, P_GLOBAL, &Globals.szDomainAdminUsers, NULL}, {"domain guest users",P_STRING, P_GLOBAL, &Globals.szDomainGuestUsers, NULL}, {"domain hosts allow",P_STRING, P_GLOBAL, &Globals.szDomainHostsallow, NULL}, @@ -863,7 +863,6 @@ FN_GLOBAL_STRING(lp_passwd_program,&Globals.szPasswdProgram) FN_GLOBAL_STRING(lp_passwd_chat,&Globals.szPasswdChat) FN_GLOBAL_STRING(lp_passwordserver,&Globals.szPasswordServer) FN_GLOBAL_STRING(lp_workgroup,&Globals.szWorkGroup) -FN_GLOBAL_STRING(lp_domain_controller,&Globals.szDomainController) FN_GLOBAL_STRING(lp_username_map,&Globals.szUsernameMap) FN_GLOBAL_STRING(lp_character_set,&Globals.szCharacterSet) FN_GLOBAL_STRING(lp_logon_script,&Globals.szLogonScript) @@ -892,6 +891,7 @@ FN_GLOBAL_BOOL(lp_dns_proxy,&Globals.bDNSproxy) FN_GLOBAL_BOOL(lp_wins_support,&Globals.bWINSsupport) FN_GLOBAL_BOOL(lp_wins_proxy,&Globals.bWINSproxy) FN_GLOBAL_BOOL(lp_local_master,&Globals.bLocalMaster) +FN_GLOBAL_BOOL(lp_domain_controller,&Globals.bDomainController) FN_GLOBAL_BOOL(lp_domain_master,&Globals.bDomainMaster) FN_GLOBAL_BOOL(lp_domain_logons,&Globals.bDomainLogons) FN_GLOBAL_BOOL(lp_preferred_master,&Globals.bPreferredMaster) diff --git a/source3/passdb/smbpass.c b/source3/passdb/smbpass.c index daa1064750..2c533f16f9 100644 --- a/source3/passdb/smbpass.c +++ b/source3/passdb/smbpass.c @@ -103,10 +103,11 @@ static int gethexpwd(char *p, char *pwd) return (True); } -/* - * Routine to search the smbpasswd file for an entry matching the username. - */ -struct smb_passwd *get_smbpwnam(char *name) +/************************************************************************* + Routine to search the smbpasswd file for an entry matching the username + or user id. if the name is NULL, then the smb_uid is used instead. + *************************************************************************/ +struct smb_passwd *get_smbpwd_entry(char *name, int smb_userid) { /* Static buffers we will return. */ static struct smb_passwd pw_buf; @@ -127,19 +128,28 @@ struct smb_passwd *get_smbpwnam(char *name) DEBUG(0, ("No SMB password file set\n")); return (NULL); } - DEBUG(10, ("get_smbpwnam: opening file %s\n", pfile)); + DEBUG(10, ("get_smbpwd_entry: opening file %s\n", pfile)); + + if (name != NULL) + { + DEBUG(10, ("get_smbpwd_entry: search by name: %s\n", name)); + } + else + { + DEBUG(10, ("get_smbpwd_entry: search by smb_userid: %x\n", smb_userid)); + } fp = fopen(pfile, "r"); if (fp == NULL) { - DEBUG(0, ("get_smbpwnam: unable to open file %s\n", pfile)); + DEBUG(0, ("get_smbpwd_entry: unable to open file %s\n", pfile)); return NULL; } /* Set a 16k buffer to do more efficient reads */ setvbuf(fp, readbuf, _IOFBF, sizeof(readbuf)); if ((lockfd = pw_file_lock(pfile, F_RDLCK, 5)) < 0) { - DEBUG(0, ("get_smbpwnam: unable to lock file %s\n", pfile)); + DEBUG(0, ("get_smbpwd_entry: unable to lock file %s\n", pfile)); fclose(fp); return NULL; } @@ -175,10 +185,10 @@ struct smb_passwd *get_smbpwnam(char *name) linebuf[linebuf_len - 1] = '\0'; #ifdef DEBUG_PASSWORD - DEBUG(100, ("get_smbpwnam: got line |%s|\n", linebuf)); + DEBUG(100, ("get_smbpwd_entry: got line |%s|\n", linebuf)); #endif if ((linebuf[0] == 0) && feof(fp)) { - DEBUG(4, ("get_smbpwnam: end of file reached\n")); + DEBUG(4, ("get_smbpwd_entry: end of file reached\n")); break; } /* @@ -195,12 +205,12 @@ struct smb_passwd *get_smbpwnam(char *name) */ if (linebuf[0] == '#' || linebuf[0] == '\0') { - DEBUG(6, ("get_smbpwnam: skipping comment or blank line\n")); + DEBUG(6, ("get_smbpwd_entry: skipping comment or blank line\n")); continue; } p = (unsigned char *) strchr(linebuf, ':'); if (p == NULL) { - DEBUG(0, ("get_smbpwnam: malformed password entry (no :)\n")); + DEBUG(0, ("get_smbpwd_entry: malformed password entry (no :)\n")); continue; } /* @@ -209,55 +219,89 @@ struct smb_passwd *get_smbpwnam(char *name) */ strncpy(user_name, linebuf, PTR_DIFF(p, linebuf)); user_name[PTR_DIFF(p, linebuf)] = '\0'; - if (!strequal(user_name, name)) - continue; - /* User name matches - get uid and password */ + /* get smb uid */ + p++; /* Go past ':' */ if (!isdigit(*p)) { - DEBUG(0, ("get_smbpwnam: malformed password entry (uid not number)\n")); + DEBUG(0, ("get_smbpwd_entry: malformed password entry (uid not number)\n")); fclose(fp); pw_file_unlock(lockfd); return NULL; } + uidval = atoi((char *) p); + while (*p && isdigit(*p)) + { p++; - if (*p != ':') { - DEBUG(0, ("get_smbpwnam: malformed password entry (no : after uid)\n")); + } + + if (*p != ':') + { + DEBUG(0, ("get_smbpwd_entry: malformed password entry (no : after uid)\n")); fclose(fp); pw_file_unlock(lockfd); return NULL; } + + if (name != NULL) + { + /* search is by user name */ + if (!strequal(user_name, name)) continue; + DEBUG(10, ("get_smbpwd_entry: found by name: %s\n", user_name)); + } + else + { + /* search is by user id */ + if (uidval != smb_userid) continue; + DEBUG(10, ("get_smbpwd_entry: found by smb_userid: %x\n", uidval)); + } + + /* if we're here, the entry has been found (either by name or uid) */ + /* * Now get the password value - this should be 32 hex digits * which are the ascii representations of a 16 byte string. * Get two at a time and put them into the password. */ + + /* skip the ':' */ p++; - if (*p == '*' || *p == 'X') { + + if (*p == '*' || *p == 'X') + { /* Password deliberately invalid - end here. */ - DEBUG(10, ("get_smbpwnam: entry invalidated for user %s\n", user_name)); + DEBUG(10, ("get_smbpwd_entry: entry invalidated for user %s\n", user_name)); fclose(fp); pw_file_unlock(lockfd); return NULL; } - if (linebuf_len < (PTR_DIFF(p, linebuf) + 33)) { - DEBUG(0, ("get_smbpwnam: malformed password entry (passwd too short)\n")); + + if (linebuf_len < (PTR_DIFF(p, linebuf) + 33)) + { + DEBUG(0, ("get_smbpwd_entry: malformed password entry (passwd too short)\n")); fclose(fp); pw_file_unlock(lockfd); return (False); } - if (p[32] != ':') { - DEBUG(0, ("get_smbpwnam: malformed password entry (no terminating :)\n")); + + if (p[32] != ':') + { + DEBUG(0, ("get_smbpwd_entry: malformed password entry (no terminating :)\n")); fclose(fp); pw_file_unlock(lockfd); return NULL; } - if (!strncasecmp((char *) p, "NO PASSWORD", 11)) { + + if (!strncasecmp((char *) p, "NO PASSWORD", 11)) + { pw_buf.smb_passwd = NULL; - } else { - if(!gethexpwd((char *)p,(char *)smbpwd)) { + } + else + { + if (!gethexpwd((char *)p, (char *)smbpwd)) + { DEBUG(0, ("Malformed Lanman password entry (non hex chars)\n")); fclose(fp); pw_file_unlock(lockfd); @@ -265,6 +309,7 @@ struct smb_passwd *get_smbpwnam(char *name) } pw_buf.smb_passwd = smbpwd; } + pw_buf.smb_name = user_name; pw_buf.smb_userid = uidval; pw_buf.smb_nt_passwd = NULL; @@ -282,7 +327,7 @@ struct smb_passwd *get_smbpwnam(char *name) fclose(fp); pw_file_unlock(lockfd); - DEBUG(5, ("get_smbpwname: returning passwd entry for user %s, uid %d\n", + DEBUG(5, ("get_smbpwd_entrye: returning passwd entry for user %s, uid %d\n", user_name, uidval)); return &pw_buf; } @@ -291,10 +336,11 @@ struct smb_passwd *get_smbpwnam(char *name) pw_file_unlock(lockfd); return NULL; } + /* * Routine to search the smbpasswd file for an entry matching the username. */ -BOOL add_smbpwnam(struct smb_passwd* pwd) +BOOL add_smbpwd_entry(struct smb_passwd* pwd) { /* Static buffers we will return. */ static pstring user_name; @@ -321,13 +367,13 @@ BOOL add_smbpwnam(struct smb_passwd* pwd) DEBUG(0, ("No SMB password file set\n")); return False; } - DEBUG(10, ("add_smbpwnam: opening file %s\n", pfile)); + DEBUG(10, ("add_smbpwd_entry: opening file %s\n", pfile)); fp = fopen(pfile, "r+"); if (fp == NULL) { - DEBUG(0, ("add_smbpwnam: unable to open file %s\n", pfile)); + DEBUG(0, ("add_smbpwd_entry: unable to open file %s\n", pfile)); return False; } /* Set a 16k buffer to do more efficient reads */ @@ -335,7 +381,7 @@ BOOL add_smbpwnam(struct smb_passwd* pwd) if ((lockfd = pw_file_lock(pfile, F_RDLCK | F_WRLCK, 5)) < 0) { - DEBUG(0, ("add_smbpwnam: unable to lock file %s\n", pfile)); + DEBUG(0, ("add_smbpwd_entry: unable to lock file %s\n", pfile)); fclose(fp); return False; } @@ -381,12 +427,12 @@ BOOL add_smbpwnam(struct smb_passwd* pwd) } #ifdef DEBUG_PASSWORD - DEBUG(100, ("add_smbpwnam: got line |%s|\n", linebuf)); + DEBUG(100, ("add_smbpwd_entry: got line |%s|\n", linebuf)); #endif if ((linebuf[0] == 0) && feof(fp)) { - DEBUG(4, ("add_smbpwnam: end of file reached\n")); + DEBUG(4, ("add_smbpwd_entry: end of file reached\n")); break; } @@ -405,7 +451,7 @@ BOOL add_smbpwnam(struct smb_passwd* pwd) if (linebuf[0] == '#' || linebuf[0] == '\0') { - DEBUG(6, ("add_smbpwnam: skipping comment or blank line\n")); + DEBUG(6, ("add_smbpwd_entry: skipping comment or blank line\n")); continue; } @@ -413,7 +459,7 @@ BOOL add_smbpwnam(struct smb_passwd* pwd) if (p == NULL) { - DEBUG(0, ("add_smbpwnam: malformed password entry (no :)\n")); + DEBUG(0, ("add_smbpwd_entry: malformed password entry (no :)\n")); continue; } @@ -425,7 +471,7 @@ BOOL add_smbpwnam(struct smb_passwd* pwd) user_name[PTR_DIFF(p, linebuf)] = '\0'; if (strequal(user_name, pwd->smb_name)) { - DEBUG(6, ("add_smbpwnam: entry already exists\n")); + DEBUG(6, ("add_smbpwd_entry: entry already exists\n")); return False; } } @@ -440,7 +486,7 @@ BOOL add_smbpwnam(struct smb_passwd* pwd) if((offpos = lseek(fd, 0, SEEK_END)) == -1) { - DEBUG(0, ("add_smbpwnam(lseek): Failed to add entry for user %s to file %s. \ + DEBUG(0, ("add_smbpwd_entry(lseek): Failed to add entry for user %s to file %s. \ Error was %s\n", pwd->smb_name, pfile, strerror(errno))); fclose(fp); @@ -452,7 +498,7 @@ Error was %s\n", pwd->smb_name, pfile, strerror(errno))); if((new_entry = (char *)malloc( new_entry_length )) == 0) { - DEBUG(0, ("add_smbpwnam(malloc): Failed to add entry for user %s to file %s. \ + DEBUG(0, ("add_smbpwd_entry(malloc): Failed to add entry for user %s to file %s. \ Error was %s\n", pwd->smb_name, pfile, strerror(errno))); @@ -482,19 +528,19 @@ Error was %s\n", sprintf(p,"\n"); #ifdef DEBUG_PASSWORD - DEBUG(100, ("add_smbpwnam(%d): new_entry_len %d entry_len %d made line |%s|\n", + DEBUG(100, ("add_smbpwd_entry(%d): new_entry_len %d entry_len %d made line |%s|\n", fd, new_entry_length, strlen(new_entry), new_entry)); #endif if ((wr_len = write(fd, new_entry, strlen(new_entry))) != strlen(new_entry)) { - DEBUG(0, ("add_smbpwnam(write): %d Failed to add entry for user %s to file %s. \ + DEBUG(0, ("add_smbpwd_entry(write): %d Failed to add entry for user %s to file %s. \ Error was %s\n", wr_len, pwd->smb_name, pfile, strerror(errno))); /* Remove the entry we just wrote. */ if(ftruncate(fd, offpos) == -1) { - DEBUG(0, ("add_smbpwnam: ERROR failed to ftruncate file %s. \ + DEBUG(0, ("add_smbpwd_entry: ERROR failed to ftruncate file %s. \ Error was %s. Password file may be corrupt ! Please examine by hand !\n", pwd->smb_name, strerror(errno))); } @@ -508,3 +554,317 @@ Error was %s. Password file may be corrupt ! Please examine by hand !\n", pw_file_unlock(lockfd); return True; } +/* + * Routine to search the smbpasswd file for an entry matching the username. + * and then modify its password entry + */ +BOOL mod_smbpwd_entry(struct smb_passwd* pwd) +{ + /* Static buffers we will return. */ + static pstring user_name; + + char linebuf[256]; + char readbuf[16 * 1024]; + unsigned char c; + char ascii_p16[66]; + unsigned char *p; + long linebuf_len; + FILE *fp; + int lockfd; + char *pfile = lp_smb_passwd_file(); + + BOOL found_entry = True; + long pwd_seekpos = 0; + + int i; + int wr_len; + int fd; + + if (!*pfile) + { + DEBUG(0, ("No SMB password file set\n")); + return False; + } + DEBUG(10, ("add_smbpwd_entry: opening file %s\n", pfile)); + + fp = fopen(pfile, "r+"); + + if (fp == NULL) + { + DEBUG(0, ("add_smbpwd_entry: unable to open file %s\n", pfile)); + return False; + } + /* Set a 16k buffer to do more efficient reads */ + setvbuf(fp, readbuf, _IOFBF, sizeof(readbuf)); + + if ((lockfd = pw_file_lock(pfile, F_RDLCK | F_WRLCK, 5)) < 0) + { + DEBUG(0, ("add_smbpwd_entry: unable to lock file %s\n", pfile)); + fclose(fp); + return False; + } + /* make sure it is only rw by the owner */ + chmod(pfile, 0600); + + /* We have a write lock on the file. */ + /* + * Scan the file, a line at a time and check if the name matches. + */ + while (!feof(fp)) + { + pwd_seekpos = ftell(fp); + + linebuf[0] = '\0'; + + fgets(linebuf, 256, fp); + if (ferror(fp)) + { + fclose(fp); + pw_file_unlock(lockfd); + return False; + } + + /* + * Check if the string is terminated with a newline - if not + * then we must keep reading and discard until we get one. + */ + linebuf_len = strlen(linebuf); + if (linebuf[linebuf_len - 1] != '\n') + { + c = '\0'; + while (!ferror(fp) && !feof(fp)) + { + c = fgetc(fp); + if (c == '\n') + { + break; + } + } + } + else + { + linebuf[linebuf_len - 1] = '\0'; + } + +#ifdef DEBUG_PASSWORD + DEBUG(100, ("add_smbpwd_entry: got line |%s|\n", linebuf)); +#endif + + if ((linebuf[0] == 0) && feof(fp)) + { + DEBUG(4, ("add_smbpwd_entry: end of file reached\n")); + break; + } + + /* + * The line we have should be of the form :- + * + * username:uid:[32hex bytes]:....other flags presently + * ignored.... + * + * or, + * + * username:uid:[32hex bytes]:[32hex bytes]:....ignored.... + * + * if Windows NT compatible passwords are also present. + */ + + if (linebuf[0] == '#' || linebuf[0] == '\0') + { + DEBUG(6, ("add_smbpwd_entry: skipping comment or blank line\n")); + continue; + } + + p = (unsigned char *) strchr(linebuf, ':'); + + if (p == NULL) + { + DEBUG(0, ("add_smbpwd_entry: malformed password entry (no :)\n")); + continue; + } + + /* + * As 256 is shorter than a pstring we don't need to check + * length here - if this ever changes.... + */ + strncpy(user_name, linebuf, PTR_DIFF(p, linebuf)); + user_name[PTR_DIFF(p, linebuf)] = '\0'; + if (strequal(user_name, pwd->smb_name)) + { + DEBUG(6, ("add_smbpwd_entry: entry already exists\n")); + found_entry = True; + break; + } + + /* User name matches - get uid and password */ + p++; /* Go past ':' */ + + if (!isdigit(*p)) + { + DEBUG(0, ("mod_smbpwd_entry: malformed password entry (uid not number)\n")); + fclose(fp); + pw_file_unlock(lockfd); + return False; + } + + while (*p && isdigit(*p)) + p++; + if (*p != ':') + { + DEBUG(0, ("mod_smbpwd_entry: malformed password entry (no : after uid)\n")); + fclose(fp); + pw_file_unlock(lockfd); + return False; + } + /* + * Now get the password value - this should be 32 hex digits + * which are the ascii representations of a 16 byte string. + * Get two at a time and put them into the password. + */ + p++; + + /* record exact password position */ + pwd_seekpos += PTR_DIFF(p, linebuf); + + if (*p == '*' || *p == 'X') + { + /* Password deliberately invalid - end here. */ + DEBUG(10, ("get_smbpwd_entry: entry invalidated for user %s\n", user_name)); + fclose(fp); + pw_file_unlock(lockfd); + return False; + } + + if (linebuf_len < (PTR_DIFF(p, linebuf) + 33)) + { + DEBUG(0, ("mod_smbpwd_entry: malformed password entry (passwd too short)\n")); + fclose(fp); + pw_file_unlock(lockfd); + return (False); + } + + if (p[32] != ':') + { + DEBUG(0, ("mod_smbpwd_entry: malformed password entry (no terminating :)\n")); + fclose(fp); + pw_file_unlock(lockfd); + return False; + } + + if (*p == '*' || *p == 'X') + { + fclose(fp); + pw_file_unlock(lockfd); + return False; + } + if (!strncasecmp((char *) p, "NO PASSWORD", 11)) + { + fclose(fp); + pw_file_unlock(lockfd); + return False; + } + + /* Now check if the NT compatible password is + available. */ + p += 33; /* Move to the first character of the line after + the lanman password. */ + if (linebuf_len < (PTR_DIFF(p, linebuf) + 33)) + { + DEBUG(0, ("mod_smbpwd_entry: malformed password entry (passwd too short)\n")); + fclose(fp); + pw_file_unlock(lockfd); + return (False); + } + + if (p[32] != ':') + { + DEBUG(0, ("mod_smbpwd_entry: malformed password entry (no terminating :)\n")); + fclose(fp); + pw_file_unlock(lockfd); + return False; + } + + if (*p == '*' || *p == 'X') + { + fclose(fp); + pw_file_unlock(lockfd); + return False; + } + + /* whew. entry is correctly formed. */ + break; + } + + /* + * Do an atomic write into the file at the position defined by + * seekpos. + */ + + /* The mod user write needs to be atomic - so get the fd from + the fp and do a raw write() call. + */ + + fd = fileno(fp); + + if (lseek(fd, pwd_seekpos - 1, SEEK_SET) != pwd_seekpos - 1) + { + DEBUG(1, ("mod_smbpwd_entry: seek fail on file %s.\n", pfile)); + fclose(fp); + pw_file_unlock(lockfd); + return False; + } + + /* Sanity check - ensure the character is a ':' */ + if (read(fd, &c, 1) != 1) + { + DEBUG(1, ("mod_smbpwd_entry: read fail on file %s.\n", pfile)); + fclose(fp); + pw_file_unlock(lockfd); + return False; + } + + if (c != ':') + { + DEBUG(1, ("mod_smbpwd_entry: check on passwd file %s failed.\n", pfile)); + fclose(fp); + pw_file_unlock(lockfd); + return False; + } + + /* Create the 32 byte representation of the new p16 */ + for (i = 0; i < 16; i++) + { + sprintf(&ascii_p16[i*2], "%02X", (uchar) pwd->smb_passwd[i]); + } + if (pwd->smb_nt_passwd != NULL) + { + /* Add on the NT md4 hash */ + ascii_p16[32] = ':'; + for (i = 0; i < 16; i++) + { + sprintf(&ascii_p16[(i*2)+33], "%02X", (uchar) pwd->smb_nt_passwd[i]); + } + wr_len = 65; + } + else + { + wr_len = 32; + } + +#ifdef DEBUG_PASSWORD + DEBUG(100,("mod_smbpwd_entry: ")); + dump_data(100, ascii_p16, wr_len); +#endif + + if (write(fd, ascii_p16, wr_len) != wr_len) + { + DEBUG(1, ("mod_smbpwd_entry: write failed in passwd file %s\n", pfile)); + fclose(fp); + pw_file_unlock(lockfd); + return False; + } + + fclose(fp); + pw_file_unlock(lockfd); + return True; +} diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c index 1943129ba6..ce14ccd9bc 100644 --- a/source3/smbd/ipc.c +++ b/source3/smbd/ipc.c @@ -144,7 +144,7 @@ static void send_trans_reply(char *outbuf,char *data,char *param,uint16 *setup, this_lparam = MIN(lparam,max_send - (500+lsetup*SIZEOFWORD)); /* hack */ this_ldata = MIN(ldata,max_send - (500+lsetup*SIZEOFWORD+this_lparam)); - align = (this_lparam%4); + align = (this_lparam%4)+1; set_message(outbuf,10+lsetup,align+this_ldata+this_lparam,True); if (this_lparam) @@ -2872,7 +2872,9 @@ struct { #ifdef NTDOMAIN { "TransactNmPipe", "lsarpc", "lsass", 0x26, api_ntLsarpcTNP }, + { "TransactNmPipe", "samr", "lsass", 0x26, api_samrTNP }, { "TransactNmPipe", "srvsvc", "lsass", 0x26, api_srvsvcTNP }, + { "TransactNmPipe", "wkssvc", "ntsvcs", 0x26, api_wkssvcTNP }, { "TransactNmPipe", "NETLOGON", "NETLOGON", 0x26, api_netlogrpcTNP }, { NULL, NULL, NULL, -1, (BOOL (*)())api_Unsupported } #else diff --git a/source3/smbd/password.c b/source3/smbd/password.c index b759f68430..185fc68f5a 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -887,7 +887,8 @@ BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd) return(False); } - smb_pass = get_smbpwnam(user); + /* non-null username indicates search by username not smb userid */ + smb_pass = get_smbpwd_entry(user, 0); if (!smb_pass) { DEBUG(3,("Couldn't find user %s in smb_passwd file.\n", user)); diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 4a2e185cb4..e2f704e6af 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -57,6 +57,8 @@ char * known_pipes [] = #if NTDOMAIN "NETLOGON", "srvsvc", + "wkssvc", + "samr", #endif NULL }; @@ -139,6 +141,8 @@ int reply_pipe_close(char *inbuf,char *outbuf) int cnum = SVAL(inbuf,smb_tid); int outsize = set_message(outbuf,0,0,True); + DEBUG(5,("reply_pipe_close: pnum:%x cnum:%x\n", pnum, cnum)); + if (!close_rpc_pipe_hnd(pnum, cnum)) return(ERROR(ERRDOS,ERRbadfid)); return(outsize); diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 46425861d4..e8d79b098c 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -498,7 +498,8 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize) /* If name ends in $ then I think it's asking about whether a */ /* computer with that name (minus the $) has access. For now */ /* say yes to everything ending in $. */ - if (user[strlen(user) - 1] == '$') { + if (user[strlen(user) - 1] == '$') + { #ifdef NTDOMAIN struct smb_passwd *smb_pass; /* To check if machine account exists */ /* @@ -511,15 +512,18 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize) a domain. This may be the source of future bugs if we cannot be sure whether to reject this or not. */ - smb_pass = get_smbpwnam(user); - if(smb_pass) + /* non-null user name indicates search by username not by smb userid */ + smb_pass = get_smbpwd_entry(user, 0); + + if (!smb_pass) { /* PAXX: This is the NO LOGON workstation trust account stuff */ - DEBUG(4,("Rejecting workstation trust account %s",user)); + DEBUG(4,("No Workstation trust account %s",user)); SSVAL(outbuf, smb_flg2, 0xc003); /* PAXX: Someone please unhack this */ CVAL(outbuf, smb_reh) = 1; /* PAXX: Someone please unhack this */ - return(ERROR(NT_STATUS_ALLOTTED_SPACE_EXCEEDED, 0xc000)); /* 0x99 NT error, 0xc00 */ + return(ERROR(NT_STATUS_LOGON_FAILURE, 0xc000)); /* 0x109 NT error, 0xc000 */ } + computer_id = True; #else /* not NTDOMAIN, leave this in. PAXX: Someone get rid of this */ user[strlen(user) - 1] = '\0'; diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 3c128872e6..e4e5872035 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -4732,6 +4732,7 @@ int construct_reply(char *inbuf,char *outbuf,int size,int bufsize) chain_size = 0; chain_fnum = -1; + reset_chain_pnum(); bzero(outbuf,smb_size); @@ -4943,6 +4944,11 @@ static void init_structs(void ) /* for RPC pipes */ init_rpc_pipe_hnd(); +#ifdef NTDOMAIN + /* for LSA handles */ + init_lsa_policy_hnd(); +#endif + init_dptrs(); } -- cgit