Moved cruft out of smb.h into ntdomain.h where it belongs. dc struct
authorJeremy Allison <jra@samba.org>
Sun, 11 Mar 2001 22:26:28 +0000 (22:26 +0000)
committerJeremy Allison <jra@samba.org>
Sun, 11 Mar 2001 22:26:28 +0000 (22:26 +0000)
now in pipe struct (where used) rather than user_struct.
Secured machine account password changing in srv_netlog_nt.c - ensure
that only the given machine can change its own password. May need to
free this up later for NT admin tools, but this is a fail-safe secure
position for now.
Jeremy.

source/include/ntdomain.h
source/include/proto.h
source/include/rpc_misc.h
source/include/smb.h
source/rpc_server/srv_netlog_nt.c
source/smbd/password.c

index a3fd51948ddc220b2f987056312bf4664c2b9480..799fa6d90726eef79ae1c708e22db3819423afe0 100644 (file)
@@ -24,7 +24,6 @@
 #ifndef _NT_DOMAIN_H /* _NT_DOMAIN_H */
 #define _NT_DOMAIN_H 
 
-
 /* dce/rpc support */
 #include "rpc_dce.h"
 
@@ -137,21 +136,6 @@ typedef struct _input_data {
     prs_struct data;
 } input_data;
 
-struct msrpc_state
-{
-    fstring pipe_name;
-    struct user_creds usr;
-    struct ntdom_info nt;
-
-    int fd;
-    BOOL redirect;
-    BOOL initialised;
-    char *inbuf;
-    char *outbuf;
-
-    uint32 pid;
-};
-
 /*
  * Handle database - stored per pipe.
  */
@@ -173,12 +157,26 @@ struct handle_list {
        size_t count;
 };
 
+/* Domain controller authentication protocol info */
+struct dcinfo
+{
+       DOM_CHAL clnt_chal; /* Initial challenge received from client */
+       DOM_CHAL srv_chal;  /* Initial server challenge */
+       DOM_CRED clnt_cred; /* Last client credential */
+       DOM_CRED srv_cred;  /* Last server credential */
+       uchar  sess_key[8]; /* Session key */
+       uchar  md4pw[16];   /* md4(machine password) */
+
+       fstring mach_acct;  /* Machine name we've authenticated. */
+};
+
 typedef struct pipes_struct
 {
        struct pipes_struct *next, *prev;
        int pnum;
        connection_struct *conn;
-       uint16 vuid;
+       uint16 vuid; /* points to the unauthenticated user that opened this pipe. */
        BOOL open; /* open connection */
        uint16 device_state;
        uint16 priority;
@@ -194,6 +192,7 @@ typedef struct pipes_struct
        unsigned char challenge[8];
        unsigned char ntlmssp_hash[258];
        uint32 ntlmssp_seq_num;
+       struct dcinfo dc; /* Keeps the creds data. */
 
        /*
         * Windows user info.
index c1271e7d277adaa4cff9d377409ddb4d4f5f08e8..774f623adb75026edb655091e108b9c7a170e80b 100644 (file)
@@ -159,38 +159,6 @@ BOOL message_send_all(TDB_CONTEXT *conn_tdb, int msg_type, void *buf, size_t len
 
 int ms_fnmatch(char *pattern, char *string);
 
-/*The following definitions come from  lib/msrpc-client.c  */
-
-BOOL receive_msrpc(int fd, prs_struct *data, unsigned int timeout);
-BOOL msrpc_send(int fd, prs_struct *ps);
-BOOL msrpc_receive(int fd, prs_struct *ps);
-BOOL msrpc_connect(struct msrpc_state *msrpc, const char *pipe_name);
-void msrpc_init_creds(struct msrpc_state *msrpc, const struct user_creds *usr);
-void msrpc_close_socket(struct msrpc_state *msrpc);
-void msrpc_sockopt(struct msrpc_state *msrpc, char *options);
-BOOL msrpc_connect_auth(struct msrpc_state *msrpc,
-                               uint32 pid,
-                               const char* pipename,
-                               const struct user_creds *usr);
-struct msrpc_state *msrpc_initialise(struct msrpc_state *msrpc, uint32 pid);
-void msrpc_shutdown(struct msrpc_state *msrpc);
-BOOL msrpc_establish_connection(struct msrpc_state *msrpc,
-               const char *pipe_name);
-
-/*The following definitions come from  lib/msrpc_use.c  */
-
-void init_msrpc_use(void);
-void free_msrpc_use(void);
-struct msrpc_state *msrpc_use_add(const char* pipe_name,
-                               uint32 pid,
-                               struct user_creds *usr_creds,
-                               BOOL redir);
-BOOL msrpc_use_del(const char* pipe_name,
-                               const struct user_creds *usr_creds,
-                               BOOL force_close,
-                               BOOL *connection_closed);
-void msrpc_net_use_enum(uint32 *num_cons, struct use_info ***use);
-
 /*The following definitions come from  lib/pidfile.c  */
 
 pid_t pidfile_pid(char *name);
index 5152df8e0f4e0053cbcbaa6ee4f1b8b826c9b4d7..428db938ded421c8f803051632b38fad65b8e683 100644 (file)
@@ -247,6 +247,19 @@ typedef struct log_info
 
 } DOM_LOG_INFO;
 
+/* DOM_CHAL - challenge info */
+typedef struct chal_info
+{
+    uchar data[8]; /* credentials */
+} DOM_CHAL;
+/* DOM_CREDs - timestamped client or server credentials */
+typedef struct cred_info
+{
+    DOM_CHAL challenge; /* credentials */
+    UTIME timestamp;    /* credential time-stamp */
+} DOM_CRED;
+
 /* DOM_CLNT_INFO - client info */
 typedef struct clnt_info
 {
index ab1cd60f66d2bd728171465fd53e02572ffbeb05..ba0a02e950703d66a8985771a92f0d8917cb8477 100644 (file)
@@ -425,25 +425,12 @@ typedef struct domain_grp_member_info
 
 } DOMAIN_GRP_MEMBER;
 
-/* DOM_CHAL - challenge info */
-typedef struct chal_info
-{
-  uchar data[8]; /* credentials */
-} DOM_CHAL;
-
 /* 32 bit time (sec) since 01jan1970 - cifs6.txt, section 3.5, page 30 */
 typedef struct time_info
 {
   uint32 time;
 } UTIME;
 
-/* DOM_CREDs - timestamped client or server credentials */
-typedef struct cred_info
-{  
-  DOM_CHAL challenge; /* credentials */
-  UTIME timestamp;    /* credential time-stamp */
-} DOM_CRED;
-
 /* Structure used when SMBwritebmpx is active */
 typedef struct
 {
@@ -581,19 +568,6 @@ struct current_user
 #define EXCLUSIVE_BREAK_SENT 1
 #define LEVEL_II_BREAK_SENT 2
 
-/* Domain controller authentication protocol info */
-struct dcinfo
-{
-  DOM_CHAL clnt_chal; /* Initial challenge received from client */
-  DOM_CHAL srv_chal;  /* Initial server challenge */
-  DOM_CRED clnt_cred; /* Last client credential */
-  DOM_CRED srv_cred;  /* Last server credential */
-
-  uchar  sess_key[8]; /* Session key */
-  uchar  md4pw[16];   /* md4(machine password) */
-};
-
-
 typedef struct {
        fstring smb_name; /* user name from the client */
        fstring unix_name; /* unix user name of a validated user */
@@ -1600,21 +1574,6 @@ struct pwd_info
        uchar sess_key[16];
 };
 
-struct ntdom_info
-{
-       unsigned char sess_key[16];        /* Current session key. */
-       unsigned char ntlmssp_hash[258];   /* ntlmssp data. */
-       uint32 ntlmssp_cli_flgs;           /* ntlmssp client flags */
-       uint32 ntlmssp_srv_flgs;           /* ntlmssp server flags */
-       uint32 ntlmssp_seq_num;            /* ntlmssp sequence number */
-       DOM_CRED clnt_cred;                /* Client credential. */
-
-       int max_recv_frag;
-       int max_xmit_frag;
-
-       vuser_key key;
-};
-
 /*
  * Network Computing Architechture Context Name Named Pipe
  * See MSDN docs for more information
@@ -1648,10 +1607,6 @@ typedef struct user_struct
        gid_t *groups;
 
        NT_USER_TOKEN *nt_user_token;
-
-       /* per-user authentication information on NT RPCs */
-       /* lkclXXXX - THIS SHOULD NOT BE HERE! */
-       struct dcinfo dc;
 } user_struct;
 
 #include "ntdomain.h"
index 764f76e0e4704b51fcd95d9160f3fecf6ac2b351..f022b6f06b48ddce13863a1f1727b06ca9017b2b 100644 (file)
@@ -150,6 +150,8 @@ static BOOL get_md4pw(char *md4pw, char *mach_acct)
        }
 #endif /* 0 */
 
+       /* JRA. This is ok as it is only used for generating the challenge. */
+
        become_root();
        sampass = pdb_getsampwnam(mach_acct);
        unbecome_root();
@@ -175,10 +177,9 @@ uint32 _net_req_chal(pipes_struct *p, NET_Q_REQ_CHAL *q_u, NET_R_REQ_CHAL *r_u)
 {
        uint32 status = NT_STATUS_NOPROBLEMO;
        fstring mach_acct;
-       user_struct *vuser;
 
-       if ((vuser = get_valid_user_struct(p->vuid)) == NULL)
-               return False;
+       if (!get_valid_user_struct(p->vuid))
+               return NT_STATUS_NO_SUCH_USER;
 
        fstrcpy(mach_acct, dos_unistrn2(q_u->uni_logon_clnt.buffer,
                                    q_u->uni_logon_clnt.uni_str_len));
@@ -186,29 +187,33 @@ uint32 _net_req_chal(pipes_struct *p, NET_Q_REQ_CHAL *q_u, NET_R_REQ_CHAL *r_u)
        strlower(mach_acct);
        fstrcat(mach_acct, "$");
 
-       if (get_md4pw((char *)vuser->dc.md4pw, mach_acct)) {
+       if (get_md4pw((char *)p->dc.md4pw, mach_acct)) {
                /* copy the client credentials */
-               memcpy(vuser->dc.clnt_chal.data          , q_u->clnt_chal.data, sizeof(q_u->clnt_chal.data));
-               memcpy(vuser->dc.clnt_cred.challenge.data, q_u->clnt_chal.data, sizeof(q_u->clnt_chal.data));
+               memcpy(p->dc.clnt_chal.data          , q_u->clnt_chal.data, sizeof(q_u->clnt_chal.data));
+               memcpy(p->dc.clnt_cred.challenge.data, q_u->clnt_chal.data, sizeof(q_u->clnt_chal.data));
 
                /* create a server challenge for the client */
                /* Set these to random values. */
-                generate_random_buffer(vuser->dc.srv_chal.data, 8, False);
+               generate_random_buffer(p->dc.srv_chal.data, 8, False);
 
-               memcpy(vuser->dc.srv_cred.challenge.data, vuser->dc.srv_chal.data, 8);
+               memcpy(p->dc.srv_cred.challenge.data, p->dc.srv_chal.data, 8);
 
-               memset((char *)vuser->dc.sess_key, '\0', sizeof(vuser->dc.sess_key));
+               memset((char *)p->dc.sess_key, '\0', sizeof(p->dc.sess_key));
 
                /* from client / server challenges and md4 password, generate sess key */
-               cred_session_key(&vuser->dc.clnt_chal, &vuser->dc.srv_chal,
-                                (char *)vuser->dc.md4pw, vuser->dc.sess_key);
+               cred_session_key(&p->dc.clnt_chal, &p->dc.srv_chal,
+                                (char *)p->dc.md4pw, p->dc.sess_key);
+
+               /* Save the machine account name. */
+               fstrcpy(p->dc.mach_acct, mach_acct);
+
        } else {
                /* lkclXXXX take a guess at a good error message to return :-) */
                status = NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT;
        }
 
        /* set up the LSA REQUEST CHALLENGE response */
-       init_net_r_req_chal(r_u, &vuser->dc.srv_chal, status);
+       init_net_r_req_chal(r_u, &p->dc.srv_chal, status);
 
        return r_u->status;
 }
@@ -223,22 +228,21 @@ uint32 _net_auth_2(pipes_struct *p, NET_Q_AUTH_2 *q_u, NET_R_AUTH_2 *r_u)
        DOM_CHAL srv_cred;
        UTIME srv_time;
        NEG_FLAGS srv_flgs;
-       user_struct *vuser;
 
-       if ((vuser = get_valid_user_struct(p->vuid)) == NULL)
+       if (!get_valid_user_struct(p->vuid))
                return NT_STATUS_NO_SUCH_USER;
 
        srv_time.time = 0;
 
        /* check that the client credentials are valid */
-       if (cred_assert(&q_u->clnt_chal, vuser->dc.sess_key, &vuser->dc.clnt_cred.challenge, srv_time)) {
+       if (cred_assert(&q_u->clnt_chal, p->dc.sess_key, &p->dc.clnt_cred.challenge, srv_time)) {
 
                /* create server challenge for inclusion in the reply */
-               cred_create(vuser->dc.sess_key, &vuser->dc.srv_cred.challenge, srv_time, &srv_cred);
+               cred_create(p->dc.sess_key, &p->dc.srv_cred.challenge, srv_time, &srv_cred);
 
                /* copy the received client credentials for use next time */
-               memcpy(vuser->dc.clnt_cred.challenge.data, q_u->clnt_chal.data, sizeof(q_u->clnt_chal.data));
-               memcpy(vuser->dc.srv_cred .challenge.data, q_u->clnt_chal.data, sizeof(q_u->clnt_chal.data));
+               memcpy(p->dc.clnt_cred.challenge.data, q_u->clnt_chal.data, sizeof(q_u->clnt_chal.data));
+               memcpy(p->dc.srv_cred .challenge.data, q_u->clnt_chal.data, sizeof(q_u->clnt_chal.data));
        } else {
                status = NT_STATUS_ACCESS_DENIED;
        }
@@ -257,24 +261,22 @@ uint32 _net_auth_2(pipes_struct *p, NET_Q_AUTH_2 *q_u, NET_R_AUTH_2 *r_u)
 
 uint32 _net_srv_pwset(pipes_struct *p, NET_Q_SRV_PWSET *q_u, NET_R_SRV_PWSET *r_u)
 {
-       uint16 vuid = p->vuid;
        uint32 status = NT_STATUS_WRONG_PASSWORD;
        DOM_CRED srv_cred;
        pstring mach_acct;
        SAM_ACCOUNT *sampass;
        BOOL ret = False;
-       user_struct *vuser;
        unsigned char pwd[16];
        int i;
 
-       if ((vuser = get_valid_user_struct(vuid)) == NULL)
+       if (!get_valid_user_struct(p->vuid))
                return NT_STATUS_NO_SUCH_USER;
 
        /* checks and updates credentials.  creates reply credentials */
-       if (!deal_with_creds(vuser->dc.sess_key, &vuser->dc.clnt_cred, &q_u->clnt_id.cred, &srv_cred))
+       if (!deal_with_creds(p->dc.sess_key, &p->dc.clnt_cred, &q_u->clnt_id.cred, &srv_cred))
                return NT_STATUS_INVALID_HANDLE;
 
-       memcpy(&vuser->dc.srv_cred, &vuser->dc.clnt_cred, sizeof(vuser->dc.clnt_cred));
+       memcpy(&p->dc.srv_cred, &p->dc.clnt_cred, sizeof(p->dc.clnt_cred));
 
        DEBUG(5,("_net_srv_pwset: %d\n", __LINE__));
 
@@ -287,15 +289,27 @@ uint32 _net_srv_pwset(pipes_struct *p, NET_Q_SRV_PWSET *q_u, NET_R_SRV_PWSET *r_
        sampass = pdb_getsampwnam(mach_acct);
        unbecome_root();
 
-       if (sampass == NULL)
+       /* Ensure the account exists and is a machine account. */
+
+       if (sampass == NULL || !(pdb_get_acct_ctrl(sampass) & ACB_WSTRUST))
                return NT_STATUS_NO_SUCH_USER;
 
+       /*
+        * Check the machine account name we're changing is the same
+        * as the one we've authenticated from. This prevents arbitrary
+        * machines changing other machine account passwords.
+        */
+
+       if (!strequal(mach_acct, p->dc.mach_acct))
+               return NT_STATUS_ACCESS_DENIED;
+
+       
        DEBUG(100,("Server password set : new given value was :\n"));
        for(i = 0; i < 16; i++)
                DEBUG(100,("%02X ", q_u->pwd[i]));
        DEBUG(100,("\n"));
 
-       cred_hash3( pwd, q_u->pwd, vuser->dc.sess_key, 0);
+       cred_hash3( pwd, q_u->pwd, p->dc.sess_key, 0);
 
        /* lies!  nt and lm passwords are _not_ the same: don't care */
        pdb_set_lanman_passwd (sampass, pwd);
@@ -324,17 +338,15 @@ uint32 _net_sam_logoff(pipes_struct *p, NET_Q_SAM_LOGOFF *q_u, NET_R_SAM_LOGOFF
 {
        DOM_CRED srv_cred;
 
-       user_struct *vuser;
-
-       if ((vuser = get_valid_user_struct(p->vuid)) == NULL)
+       if (!get_valid_user_struct(p->vuid))
                return NT_STATUS_NO_SUCH_USER;
 
        /* checks and updates credentials.  creates reply credentials */
-       if (!deal_with_creds(vuser->dc.sess_key, &vuser->dc.clnt_cred, 
+       if (!deal_with_creds(p->dc.sess_key, &p->dc.clnt_cred, 
                        &q_u->sam_id.client.cred, &srv_cred))
                return NT_STATUS_INVALID_HANDLE;
 
-       memcpy(&vuser->dc.srv_cred, &vuser->dc.clnt_cred, sizeof(vuser->dc.clnt_cred));
+       memcpy(&p->dc.srv_cred, &p->dc.clnt_cred, sizeof(p->dc.clnt_cred));
 
        /* XXXX maybe we want to say 'no', reject the client's credentials */
        r_u->buffer_creds = 1; /* yes, we have valid server credentials */
@@ -349,7 +361,7 @@ uint32 _net_sam_logoff(pipes_struct *p, NET_Q_SAM_LOGOFF *q_u, NET_R_SAM_LOGOFF
  net_login_interactive:
  *************************************************************************/
 
-static uint32 net_login_interactive(NET_ID_INFO_1 *id1, SAM_ACCOUNT *sampass, user_struct *vuser)
+static uint32 net_login_interactive(NET_ID_INFO_1 *id1, SAM_ACCOUNT *sampass, pipes_struct *p)
 {
        uint32 status = 0x0;
 
@@ -358,7 +370,7 @@ static uint32 net_login_interactive(NET_ID_INFO_1 *id1, SAM_ACCOUNT *sampass, us
        unsigned char key[16];
 
        memset(key, 0, 16);
-       memcpy(key, vuser->dc.sess_key, 8);
+       memcpy(key, p->dc.sess_key, 8);
 
        memcpy(lm_pwd, id1->lm_owf.data, 16);
        memcpy(nt_pwd, id1->nt_owf.data, 16);
@@ -444,28 +456,26 @@ static uint32 net_login_network(NET_ID_INFO_2 *id2, SAM_ACCOUNT *sampass)
 uint32 _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *r_u)
 {
        uint32 status = NT_STATUS_NOPROBLEMO;
-    uint16 vuid = p->vuid;
     NET_USER_INFO_3 *usr_info = NULL;
     DOM_CRED srv_cred;
     SAM_ACCOUNT *sampass = NULL;
        uint16 acct_ctrl;
     UNISTR2 *uni_samlogon_user = NULL;
     fstring nt_username;
-    user_struct *vuser = NULL;
    
        usr_info = (NET_USER_INFO_3 *)talloc(p->mem_ctx, sizeof(NET_USER_INFO_3));
        if (!usr_info)
                return NT_STATUS_NO_MEMORY;
        ZERO_STRUCTP(usr_info);
  
-    if ((vuser = get_valid_user_struct(vuid)) == NULL)
+    if (!get_valid_user_struct(p->vuid))
         return NT_STATUS_NO_SUCH_USER;
     
     /* checks and updates credentials.  creates reply credentials */
-    if (!deal_with_creds(vuser->dc.sess_key, &vuser->dc.clnt_cred, &q_u->sam_id.client.cred, &srv_cred))
+    if (!deal_with_creds(p->dc.sess_key, &p->dc.clnt_cred, &q_u->sam_id.client.cred, &srv_cred))
         return NT_STATUS_INVALID_HANDLE;
     else
-        memcpy(&vuser->dc.srv_cred, &vuser->dc.clnt_cred, sizeof(vuser->dc.clnt_cred));
+        memcpy(&p->dc.srv_cred, &p->dc.clnt_cred, sizeof(p->dc.clnt_cred));
     
     /* find the username */
     
@@ -516,7 +526,7 @@ uint32 _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *r_
                switch (q_u->sam_id.logon_level) {
                case INTERACTIVE_LOGON_TYPE:
                        /* interactive login. */
-                       status = net_login_interactive(&q_u->sam_id.ctr->auth.id1, sampass, vuser);
+                       status = net_login_interactive(&q_u->sam_id.ctr->auth.id1, sampass, p);
                        break;
                case NET_LOGON_TYPE:
                        /* network login.  lm challenge and 24 byte responses */
index 9731b4140cea8420156fbb00c542a83114a07f8c..12f7385f06c891250b89e04a830cff052def77c8 100644 (file)
@@ -313,8 +313,6 @@ uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name,
                }
        }
 
-       memset(&vuser->dc, '\0', sizeof(vuser->dc));
-
        return vuser->vuid;
 }