following a cvs error, i am rewriting this monster-commit. with bad grace.
authorLuke Leighton <lkcl@samba.org>
Thu, 6 Nov 1997 23:03:58 +0000 (23:03 +0000)
committerLuke Leighton <lkcl@samba.org>
Thu, 6 Nov 1997 23:03:58 +0000 (23:03 +0000)
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.

12 files changed:
source/include/proto.h
source/include/smb.h
source/namedbwork.c
source/nameelect.c
source/namelogon.c
source/param/loadparm.c
source/passdb/smbpass.c
source/smbd/ipc.c
source/smbd/password.c
source/smbd/pipes.c
source/smbd/reply.c
source/smbd/server.c

index 4054a12c19d6c867be79efa90ac9181b7b7fdcb9..5bb709858f3ba68e32f94be4a9268e21b7ff89cc 100644 (file)
@@ -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  */
 
index 892c31be97e6ebe2243e6f7b1bf41e02ec0ea7d3..83e1d9f85d4444d6ff290d0b41ad7aa611119fb8 100644 (file)
@@ -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;
index a6260aab4675c4362b89172ff7d333d47a192b80..b01eb927e80a18d360b2cb9bc88559614ff1eda1 100644 (file)
@@ -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;
index 391320e84f89300b7d0de4e16a6271c1d544f3e6..ae4dc0857ab2baf76d378f14ce26f21121835a15 100644 (file)
@@ -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;
   
index d8e0fcfc7681e9bdac212d8617940b1c1c8f49b9..697a11a16a4494f279ec6d75cf2827be01ec0138 100644 (file)
@@ -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)
                        {
index 2fe616f70996874f3e978cf1c44c0beb9100f198..69c5fbd5c23e6f12bed6a03b5ce126b9fb7c97ab 100644 (file)
@@ -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)
index daa1064750f31d5f944f66eb590c8c61efbabaec..2c533f16f9e1987532d0df823a546428df76b3ac 100644 (file)
@@ -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;
+}
index 1943129ba6e82712569a3889eca185e3d1f63e11..ce14ccd9bc003086e05151e0278e4690717f55a2 100644 (file)
@@ -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
index b759f684304d799cea55c19ef19793c8465c9fb5..185fc68f5a36cbb19a150efbd3aa73c4597311b6 100644 (file)
@@ -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));
index 4a2e185cb405e38f41280295909865db77612b9f..e2f704e6af988158c54db9c4ebe54e83c8d365f3 100644 (file)
@@ -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);
index 46425861d42e2e0f493c22ff066bd6a59c3c8d70..e8d79b098c9435574523111c507f6b94f36ea06e 100644 (file)
@@ -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';
index 3c128872e657c752cde2c0b558413bb74f8f2c30..e4e5872035b6f5a76955a6a8bb606fb3dd8000c2 100644 (file)
@@ -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();
 }