This is the netlogon schannel client code. Try a
authorVolker Lendecke <vlendec@samba.org>
Wed, 9 Apr 2003 15:54:17 +0000 (15:54 +0000)
committerVolker Lendecke <vlendec@samba.org>
Wed, 9 Apr 2003 15:54:17 +0000 (15:54 +0000)
rpcclient -S pdc -U% -c "samlogon user password"

and it should work with the schannel. Needs testing against platforms
different from NT4SP6.

Volker

source/include/client.h
source/include/smb.h
source/libsmb/clientgen.c
source/param/loadparm.c
source/rpc_client/cli_pipe.c
source/rpc_parse/parse_rpc.c
source/rpcclient/cmd_netlogon.c
source/rpcclient/rpcclient.c
source/utils/net_rpc_samsync.c

index 0ea793de689c4caec3e2af2bf8e2be0d9e22afb5..d75effd7d04943f11170720f847332f23daa7a13 100644 (file)
@@ -132,6 +132,12 @@ struct cli_state {
         */
 
        uint16 nt_pipe_fnum;               /* Pipe handle. */
+
+       uint16 saved_netlogon_pipe_fnum;   /* The "first" pipe to get
+                                              the session key for the
+                                              schannel. */
+       struct netsec_auth_struct auth_info;
+
        unsigned char sess_key[16];        /* Current session key. */
        unsigned char ntlmssp_hash[258];   /* ntlmssp data. */
        uint32 ntlmssp_cli_flgs;           /* ntlmssp client flags */
index edd25fb44ebe7a69fab5da1351449e8069ec59ed..5baec705f5a9e80e2f4e1b191d71ef82998534ed 100644 (file)
@@ -187,6 +187,8 @@ typedef smb_ucs2_t wfstring[FSTRING_LEN];
 #define PIPE_SPOOLSS  "\\PIPE\\spoolss"
 #define PIPE_NETDFS   "\\PIPE\\netdfs"
 
+#define PIPE_NETLOGON_PLAIN "\\NETLOGON"
+
 #define PI_LSARPC              0
 #define PI_LSARPC_DS           1
 #define PI_SAMR                        2
index d96919308942d1fdb5fa4afc249d9bf15a02f09e..81b3bbcab553ad4fba45061c3ddf7b2c9534363f 100644 (file)
@@ -275,6 +275,7 @@ struct cli_state *cli_initialise(struct cli_state *cli)
        memset(cli->inbuf, 0, cli->bufsize);
 
        cli->nt_pipe_fnum = 0;
+       cli->saved_netlogon_pipe_fnum = 0;
 
        cli->initialised = 1;
        cli->allocated = alloced_cli;
index 807f8607f19b95c92833672da1b2c68fc5290312..0c07f575c1e60d755798edbd7edb905fbcb49e87 100644 (file)
@@ -230,6 +230,7 @@ typedef struct
        BOOL bDomainLogons;
        BOOL bEncryptPasswords;
        BOOL bUpdateEncrypt;
+       int  clientSchannel;
        int  serverSchannel;
        BOOL bStripDot;
        BOOL bNullPasswords;
@@ -736,6 +737,7 @@ static struct parm_struct parm_table[] = {
        {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
        {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
        {"update encrypted", P_BOOL, P_GLOBAL, &Globals.bUpdateEncrypt, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
+       {"client schannel", P_ENUM, P_GLOBAL, &Globals.clientSchannel, NULL, enum_bool_auto, FLAG_BASIC},
        {"server schannel", P_ENUM, P_GLOBAL, &Globals.serverSchannel, NULL, enum_bool_auto, FLAG_BASIC},
        {"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
        {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
@@ -1333,6 +1335,7 @@ static void init_globals(void)
        Globals.paranoid_server_security = True;
        Globals.bEncryptPasswords = True;
        Globals.bUpdateEncrypt = False;
+       Globals.clientSchannel = Auto;
        Globals.serverSchannel = Auto;
        Globals.bReadRaw = True;
        Globals.bWriteRaw = True;
@@ -1662,6 +1665,7 @@ FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
 FN_GLOBAL_BOOL(lp_strip_dot, &Globals.bStripDot)
 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
 FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
+FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
 FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
 FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
 FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
index bbbf194fbd204f872ca05518735c8be7fcc7e8e2..c4a9b37127e1e530e45101c8746ae9d11a6b6343 100644 (file)
@@ -191,6 +191,7 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, int len, int
 
        BOOL auth_verify = ((cli->ntlmssp_srv_flgs & NTLMSSP_NEGOTIATE_SIGN) != 0);
        BOOL auth_seal = ((cli->ntlmssp_srv_flgs & NTLMSSP_NEGOTIATE_SEAL) != 0);
+       BOOL auth_schannel = (cli->saved_netlogon_pipe_fnum != 0);
 
        DEBUG(5,("rpc_auth_pipe: len: %d auth_len: %d verify %s seal %s\n",
                  len, auth_len, BOOLSTR(auth_verify), BOOLSTR(auth_seal)));
@@ -293,6 +294,48 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, int len, int
                }
                cli->ntlmssp_seq_num++;
        }
+
+       if (auth_schannel) {
+               RPC_AUTH_NETSEC_CHK chk;
+               char data[RPC_AUTH_NETSEC_CHK_LEN];
+               char *dp = prs_data_p(rdata) + len - auth_len;
+               prs_struct auth_verf;
+
+               if (auth_len != RPC_AUTH_NETSEC_CHK_LEN) {
+                       DEBUG(0,("rpc_auth_pipe: wrong auth len %d\n", auth_len));
+                       return False;
+               }
+
+               if (dp - prs_data_p(rdata) > prs_data_size(rdata)) {
+                       DEBUG(0,("rpc_auth_pipe: auth data > data size !\n"));
+                       return False;
+               }
+
+               DEBUG(10,("rpc_auth_pipe: verify netsec\n"));
+               dump_data(100, dp, auth_len);
+
+               memcpy(data, dp, sizeof(data));
+               dump_data(100, data, sizeof(data));
+
+               prs_init(&auth_verf, 0, cli->mem_ctx, UNMARSHALL);
+
+               /* The endinness must be preserved. JRA. */
+               prs_set_endian_data( &auth_verf, rdata->bigendian_data);
+
+               prs_give_memory(&auth_verf, data, RPC_AUTH_NETSEC_CHK_LEN, False);
+
+               if (!smb_io_rpc_auth_netsec_chk("auth_sign", &chk, &auth_verf, 0)) {
+                       DEBUG(0, ("rpc_auth_pipe: unmarshalling "
+                                 "RPC_AUTH_NETSECK_CHK failed\n"));
+                       return False;
+               }
+
+               if (!netsec_decode(&cli->auth_info, &chk, reply_data, data_len)) {
+                       DEBUG(0, ("rpc_auth_pipe: Could not decode schannel\n"));
+                       return False;
+               }
+               cli->auth_info.seq_num++;
+       }
        return True;
 }
 
@@ -542,7 +585,7 @@ static BOOL rpc_api_pipe(struct cli_state *cli, prs_struct *data, prs_struct *rd
 
  ********************************************************************/
 
-static BOOL create_rpc_bind_req(prs_struct *rpc_out, BOOL do_auth, uint32 rpc_call_id,
+static BOOL create_rpc_bind_req(prs_struct *rpc_out, BOOL do_auth, BOOL do_netsec, uint32 rpc_call_id,
                                 RPC_IFACE *abstract, RPC_IFACE *transfer,
                                 const char *my_name, const char *domain, uint32 neg_flags)
 {
@@ -596,6 +639,43 @@ static BOOL create_rpc_bind_req(prs_struct *rpc_out, BOOL do_auth, uint32 rpc_ca
                auth_len = prs_offset(&auth_info) - RPC_HDR_AUTH_LEN;
        }
 
+       if (do_netsec) {
+               RPC_HDR_AUTH hdr_auth;
+               RPC_AUTH_NETSEC_NEG netsec_neg;
+
+               /*
+                * Create the auth structs we will marshall.
+                */
+
+               init_rpc_hdr_auth(&hdr_auth, NETSEC_AUTH_TYPE, NETSEC_AUTH_LEVEL,
+                                 0x00, 1);
+               init_rpc_auth_netsec_neg(&netsec_neg, my_name, domain);
+
+               /*
+                * Use the 4k buffer to store the auth info.
+                */
+
+               prs_give_memory( &auth_info, buffer, sizeof(buffer), False);
+
+               /*
+                * Now marshall the data into the temporary parse_struct.
+                */
+
+               if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &auth_info, 0)) {
+                       DEBUG(0,("Failed to marshall RPC_HDR_AUTH.\n"));
+                       return False;
+               }
+
+               if(!smb_io_rpc_auth_netsec_neg("netsec_neg",
+                                              &netsec_neg, &auth_info, 0)) {
+                       DEBUG(0,("Failed to marshall RPC_AUTH_NETSEC_NEG.\n"));
+                       return False;
+               }
+
+               /* Auth len in the rpc header doesn't include auth_header. */
+               auth_len = prs_offset(&auth_info) - RPC_HDR_AUTH_LEN;
+       }
+
        /* create the request RPC_HDR */
        init_rpc_hdr(&hdr, RPC_BIND, 0x3, rpc_call_id, 
                RPC_HEADER_LEN + RPC_HDR_RB_LEN + prs_offset(&auth_info),
@@ -747,9 +827,9 @@ static uint32 create_rpc_request(prs_struct *rpc_out, uint8 op_num, int data_len
         */
 
        if (auth_len != 0)
-               alloc_hint = data_left - RPC_HEADER_LEN - RPC_HDR_AUTH_LEN - auth_len;
+               alloc_hint = data_len - RPC_HEADER_LEN - RPC_HDR_AUTH_LEN - auth_len;
        else
-               alloc_hint = data_left - RPC_HEADER_LEN;
+               alloc_hint = data_len - RPC_HEADER_LEN;
 
        DEBUG(10,("create_rpc_request: data_len: %x auth_len: %x alloc_hint: %x\n",
                   data_len, auth_len, alloc_hint));
@@ -771,10 +851,10 @@ static uint32 create_rpc_request(prs_struct *rpc_out, uint8 op_num, int data_len
 }
 
 /*******************************************************************
- Puts an auth header into an rpc request.
+ Puts an NTLMSSP auth header into an rpc request.
  ********************************************************************/
 
-static BOOL create_auth_hdr(prs_struct *outgoing_packet, BOOL auth_verify)
+static BOOL create_ntlmssp_auth_hdr(prs_struct *outgoing_packet, BOOL auth_verify)
 {
        RPC_HDR_AUTH hdr_auth;
 
@@ -789,6 +869,24 @@ static BOOL create_auth_hdr(prs_struct *outgoing_packet, BOOL auth_verify)
        return True;
 }
 
+/*******************************************************************
+ Puts a NETLOGON schannel auth header into an rpc request.
+ ********************************************************************/
+
+static BOOL create_netsec_auth_hdr(prs_struct *outgoing_packet, int padding)
+{
+       RPC_HDR_AUTH hdr_auth;
+
+       init_rpc_hdr_auth(&hdr_auth, NETSEC_AUTH_TYPE,
+                         NETSEC_AUTH_LEVEL, padding, 1);
+       if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, 
+                               outgoing_packet, 0)) {
+               DEBUG(0,("create_auth_hdr:Failed to marshal RPC_HDR_AUTH.\n"));
+               return False;
+       }
+       return True;
+}
+
 /*******************************************************************
  Puts auth data into an rpc request.
  ********************************************************************/
@@ -825,19 +923,26 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num,
 {
        uint32 auth_len, max_data, data_left, data_sent;
        BOOL ret = False;
-       BOOL auth_verify, auth_seal;
+       BOOL auth_verify, auth_seal, auth_schannel;
        fstring dump_name;
 
        auth_verify = ((cli->ntlmssp_srv_flgs & NTLMSSP_NEGOTIATE_SIGN) != 0);
        auth_seal   = ((cli->ntlmssp_srv_flgs & NTLMSSP_NEGOTIATE_SEAL) != 0);
+       auth_schannel = (cli->saved_netlogon_pipe_fnum != 0);
+
+       auth_len = 0;
 
-       auth_len = (auth_verify ? RPC_AUTH_NTLMSSP_CHK_LEN : 0);
+       if (auth_verify)
+               auth_len = RPC_AUTH_NTLMSSP_CHK_LEN;
+
+       if (auth_schannel)
+               auth_len = RPC_AUTH_NETSEC_CHK_LEN;
 
        /*
         * calc how much actual data we can send in a PDU fragment
         */
        max_data = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
-               (auth_verify ? RPC_HDR_AUTH_LEN : 0) - auth_len;
+               (auth_verify ? RPC_HDR_AUTH_LEN : 0) - auth_len - 8;
 
        for (data_left = prs_offset(data), data_sent = 0; data_left > 0;) {
                prs_struct outgoing_packet;
@@ -845,13 +950,28 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num,
                uint8 flags = 0;
                uint32 crc32 = 0;
                uint32 callid = 0;
+               uint32 auth_padding = 0;
+               RPC_AUTH_NETSEC_CHK verf;
 
                /*
                 * how much will we send this time
                 */
                send_size = MIN(data_left, max_data);
+
+               /*
+                * NT expects the data that is sealed to be 8-byte
+                * aligned. The padding must be encrypted as well and
+                * taken into account when generating the
+                * authentication verifier. The amount of padding must
+                * be stored in the auth header.
+                */
+
+               if (auth_schannel)
+                       auth_padding = 8 - (send_size & 7);
+
                data_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + send_size +
-                       (auth_verify ? RPC_HDR_AUTH_LEN : 0) + auth_len;
+                       ((auth_verify|auth_schannel) ? RPC_HDR_AUTH_LEN : 0) +
+                       auth_len + auth_padding;
 
                /*
                 * Malloc parse struct to hold it (and enough for alignments).
@@ -891,18 +1011,65 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num,
                /*
                 * Now copy the data into the outgoing packet.
                 */
-               if(!prs_append_some_prs_data(&outgoing_packet, data, 
-                                            data_sent, send_size)) {
-                       DEBUG(0,("rpc_api_pipe_req: Failed to append data to outgoing packet.\n"));
-                       prs_mem_free(&outgoing_packet);
-                       return False;
+
+               if (auth_schannel) {
+                       static const uchar netsec_sig[8] = NETSEC_SIGNATURE;
+                       static const uchar nullbytes[8] = { 0,0,0,0,0,0,0,0 };
+                       uchar sign[8];
+                       BOOL ret;
+                       int i;
+                       prs_struct netsec_blob;
+
+                       memset(sign, 0, sizeof(sign));
+                       sign[4] = 0x80;
+
+                       if (!prs_init(&netsec_blob, send_size+auth_padding,
+                                     cli->mem_ctx, MARSHALL)) {
+                               DEBUG(0,("Could not malloc %u bytes",
+                                        send_size+auth_padding));
+                               prs_mem_free(&outgoing_packet);
+                               return False;
+                       }
+
+                       if(!prs_append_some_prs_data(&netsec_blob, data, 
+                                                    data_sent, send_size)) {
+                               DEBUG(0,("Failed to append data to netsec blob\n"));
+                               prs_mem_free(&outgoing_packet);
+                               return False;
+                       }
+
+                       netsec_blob.align = 8;
+
+                       if (!prs_align(&netsec_blob)) {
+                               DEBUG(0,("Could not align netsec blob\n"));
+                               prs_mem_free(&outgoing_packet);
+                               return False;
+                       }
+
+                       init_rpc_auth_netsec_chk(&verf, netsec_sig, nullbytes,
+                                                sign, nullbytes);
+
+                       netsec_encode(&(cli->auth_info), &verf,
+                                     prs_data_p(&netsec_blob),
+                                     prs_data_size(&netsec_blob));
+
+                       prs_append_prs_data(&outgoing_packet, &netsec_blob);
+                       prs_mem_free(&netsec_blob);
+               } else {
+                       if(!prs_append_some_prs_data(&outgoing_packet, data, 
+                                                    data_sent, send_size)) {
+                               DEBUG(0,("rpc_api_pipe_req: Failed to append "
+                                        "data to outgoing packet.\n"));
+                               prs_mem_free(&outgoing_packet);
+                               return False;
+                       }
                }
 
                /*
                 * Add a trailing auth_verifier if needed.
                 */
                if (auth_seal || auth_verify) {
-                       if(!create_auth_hdr(&outgoing_packet, auth_verify)) {
+                       if(!create_ntlmssp_auth_hdr(&outgoing_packet, auth_verify)) {
                                prs_mem_free(&outgoing_packet);
                                return False;
                        }
@@ -918,6 +1085,21 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num,
                        }
                }
 
+               if (auth_schannel) {
+
+                       if (!create_netsec_auth_hdr(&outgoing_packet,
+                                                   auth_padding)) {
+                               prs_mem_free(&outgoing_packet);
+                               return False;
+                       }
+
+                       if (!smb_io_rpc_auth_netsec_chk("", &verf,
+                                                       &outgoing_packet, 0)) {
+                               prs_mem_free(&outgoing_packet);
+                               return False;
+                       }
+               }
+
                DEBUG(100,("data_len: %x data_calc_len: %x\n", data_len, 
                           prs_offset(&outgoing_packet)));
                
@@ -1191,7 +1373,8 @@ static BOOL rpc_send_auth_reply(struct cli_state *cli, prs_struct *rdata, uint32
  Do an rpc bind.
 ****************************************************************************/
 
-BOOL rpc_pipe_bind(struct cli_state *cli, int pipe_idx, const char *my_name)
+static BOOL rpc_pipe_bind(struct cli_state *cli, int pipe_idx, const char *my_name,
+                         BOOL do_netsec)
 {
        RPC_IFACE abstract;
        RPC_IFACE transfer;
@@ -1220,7 +1403,7 @@ BOOL rpc_pipe_bind(struct cli_state *cli, int pipe_idx, const char *my_name)
        rpc_call_id = get_rpc_call_id();
 
        /* Marshall the outgoing data. */
-       create_rpc_bind_req(&rpc_out, do_auth, rpc_call_id,
+       create_rpc_bind_req(&rpc_out, do_auth, do_netsec, rpc_call_id,
                            &abstract, &transfer,
                            global_myname(), cli->domain, cli->ntlmssp_cli_flgs);
 
@@ -1310,7 +1493,7 @@ BOOL cli_nt_session_open(struct cli_state *cli, const int pipe_idx)
 
        /******************* bind request on pipe *****************/
 
-       if (!rpc_pipe_bind(cli, pipe_idx, global_myname())) {
+       if (!rpc_pipe_bind(cli, pipe_idx, global_myname(), False)) {
                DEBUG(2,("cli_nt_session_open: rpc bind to %s failed\n",
                         get_pipe_name_from_index(pipe_idx)));
                cli_close(cli, cli->nt_pipe_fnum);
@@ -1340,6 +1523,106 @@ BOOL cli_nt_session_open(struct cli_state *cli, const int pipe_idx)
 }
 
 
+/****************************************************************************
+ Open a session to the NETLOGON pipe using schannel.
+ ****************************************************************************/
+
+BOOL cli_nt_open_netlogon(struct cli_state *cli, const char *trust_password,
+                         int sec_chan)
+{
+       NTSTATUS result;
+       uint32 neg_flags = 0x000001ff;
+       int fnum;
+
+       if (lp_client_schannel() != False)
+               neg_flags |= NETLOGON_NEG_SCHANNEL;
+
+
+       if (!cli_nt_session_open(cli, PI_NETLOGON)) {
+               return False;
+       }
+
+       if (!secrets_init()) {
+               DEBUG(3,("Failed to init secrets.tdb\n"));
+               return False;
+       }
+
+       result = cli_nt_setup_creds(cli, sec_chan, trust_password,
+                                   &neg_flags, 2);
+
+       if (!NT_STATUS_IS_OK(result)) {
+               cli_nt_session_close(cli);
+               return False;
+       }
+
+       if ((lp_client_schannel() == True) &&
+           ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
+
+               DEBUG(3, ("Server did not offer schannel\n"));
+               cli_nt_session_close(cli);
+               return False;
+       }
+
+       if ((lp_client_schannel() == False) ||
+           ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
+               return True;
+       }
+
+       /* Server offered schannel, so try it. */
+
+       cli->auth_info.seq_num = 0;
+       memcpy(cli->auth_info.sess_key, cli->sess_key,
+              sizeof(cli->auth_info.sess_key));
+
+       cli->saved_netlogon_pipe_fnum = cli->nt_pipe_fnum;
+
+       if (cli->capabilities & CAP_NT_SMBS) {
+
+               /* If we open \\PIPE\NETLOGON here, NT4SP6
+                  gives us an ACCESS_DENIED. Do I have to
+                  understand this?
+               */
+               if ((fnum = cli_nt_create(cli, PIPE_NETLOGON_PLAIN,
+                                         DESIRED_ACCESS_PIPE)) == -1) {
+                       DEBUG(0,("cli_nt_create failed to %s machine %s. "
+                                "Error was %s\n",
+                                PIPE_NETLOGON, cli->desthost,
+                                cli_errstr(cli)));
+                       return False;
+               }
+               
+               cli->nt_pipe_fnum = (uint16)fnum;
+       } else {
+               if ((fnum = cli_open(cli, PIPE_NETLOGON,
+                                    O_CREAT|O_RDWR, DENY_NONE)) == -1) {
+                       DEBUG(0,("cli_open failed on pipe %s to machine %s. "
+                                "Error was %s\n",
+                                PIPE_NETLOGON, cli->desthost,
+                                cli_errstr(cli)));
+                       return False;
+               }
+
+               cli->nt_pipe_fnum = (uint16)fnum;
+
+               /**************** Set Named Pipe State ***************/
+               if (!rpc_pipe_set_hnd_state(cli, PIPE_NETLOGON, 0x4300)) {
+                       DEBUG(0,("Pipe hnd state failed.  Error was %s\n",
+                                 cli_errstr(cli)));
+                       cli_close(cli, cli->nt_pipe_fnum);
+                       return False;
+               }
+       }
+
+       if (!rpc_pipe_bind(cli, PI_NETLOGON, global_myname(), True)) {
+               DEBUG(2,("rpc bind to %s failed\n", PIPE_NETLOGON));
+               cli_close(cli, cli->nt_pipe_fnum);
+               return False;
+       }
+
+       return True;
+}
+
+
 const char *cli_pipe_get_name(struct cli_state *cli)
 {
        return cli->pipe_name;
@@ -1352,6 +1635,10 @@ close the session
 
 void cli_nt_session_close(struct cli_state *cli)
 {
+       if (cli->saved_netlogon_pipe_fnum != 0) {
+               cli_close(cli, cli->saved_netlogon_pipe_fnum);
+               cli->saved_netlogon_pipe_fnum = 0;
+       }
        cli_close(cli, cli->nt_pipe_fnum);
        cli->nt_pipe_fnum = 0;
 }
index 700ce8cfd6e441482f6d8543c36e0660b12811b8..656082e05ae0ee0fc4b0bc61040ee072bb50d18b 100644 (file)
@@ -1128,6 +1128,18 @@ BOOL smb_io_rpc_auth_ntlmssp_chk(const char *desc, RPC_AUTH_NTLMSSP_CHK *chk, pr
        return True;
 }
 
+/*******************************************************************
+creates an RPC_AUTH_NETSEC_NEG structure.
+********************************************************************/
+void init_rpc_auth_netsec_neg(RPC_AUTH_NETSEC_NEG *neg,
+                             const char *domain, const char *myname)
+{
+       neg->unknown1 = 0;
+       neg->unknown2 = 0x13;
+       fstrcpy(neg->domain, domain);
+       fstrcpy(neg->myname, myname);
+}
+
 /*******************************************************************
  Reads or writes an RPC_AUTH_NETSEC_NEG structure.
 ********************************************************************/
@@ -1148,11 +1160,11 @@ BOOL smb_io_rpc_auth_netsec_neg(const char *desc, RPC_AUTH_NETSEC_NEG *neg,
                return False;
        if(!prs_uint32("unknown2", ps, depth, &neg->unknown2))
                return False;
-       if(!prs_string("domain  ", ps, depth, neg->domain,
-                      strlen(&ps->data_p[ps->data_offset]), sizeof(neg->domain)))
-               return False;
        if(!prs_string("myname  ", ps, depth, neg->myname, 
-                      strlen(&ps->data_p[ps->data_offset]), sizeof(neg->myname)))
+                      strlen(neg->myname), sizeof(neg->myname)))
+               return False;
+       if(!prs_string("domain  ", ps, depth, neg->domain,
+                      strlen(neg->domain), sizeof(neg->domain)))
                return False;
 
        return True;
index 1421c4da268c949417094bf52d5bb61e8c3f030c..e6ec28beabbaf69306c98dbcacd754c9e95868ac 100644 (file)
@@ -296,25 +296,6 @@ static NTSTATUS cmd_netlogon_sam_logon(struct cli_state *cli,
        if (argc == 6)
                 sscanf(argv[5], "%i", &auth_level);
 
-        /* Authenticate ourselves with the domain controller */
-
-        if (!secrets_init()) {
-                fprintf(stderr, "Unable to initialise secrets database\n");
-                return result;
-        }
-
-       if (!secrets_fetch_trust_account_password(lp_workgroup(), trust_passwd, NULL)) {
-               fprintf(stderr, "could not fetch trust account password\n");
-               goto done;
-       }        
-
-        result = cli_nt_setup_creds(cli, get_sec_chan(), trust_passwd, &neg_flags, auth_level);
-
-        if (!NT_STATUS_IS_OK(result)) {
-                fprintf(stderr, "Error initialising session creds\n");
-                goto done;
-        }
-
         /* Perform the sam logon */
 
         result = cli_netlogon_sam_logon(cli, mem_ctx, username, password, logon_type);
index 2338d72f19273cf3941ff8dd8150cff0bb50196d..0cb4ba98c865b2da2b392e725f77167819c6dc78 100644 (file)
@@ -475,11 +475,28 @@ static NTSTATUS do_cmd(struct cli_state *cli,
 
        /* Open pipe */
 
-       if (cmd_entry->pipe_idx != -1)
-               if (!cli_nt_session_open(cli, cmd_entry->pipe_idx)) {
-                       DEBUG(0, ("Could not initialize pipe\n"));
+       if (cmd_entry->pipe_idx == PI_NETLOGON) {
+               uchar trust_password[16];
+
+               if (!secrets_fetch_trust_account_password(lp_workgroup(),
+                                                         trust_password,
+                                                         NULL)) {
+                       return NT_STATUS_UNSUCCESSFUL;
+               }
+
+               if (!cli_nt_open_netlogon(cli, trust_password,
+                                         SEC_CHAN_WKSTA)) {
+                       DEBUG(0, ("Could not initialize NETLOGON pipe\n"));
                        return NT_STATUS_UNSUCCESSFUL;
                }
+       } else {
+               if (cmd_entry->pipe_idx != -1) {
+                       if (!cli_nt_session_open(cli, cmd_entry->pipe_idx)) {
+                               DEBUG(0, ("Could not initialize pipe\n"));
+                               return NT_STATUS_UNSUCCESSFUL;
+                       }
+               }
+       }
 
      /* Run command */
 
index 9367404b3544b3c0d6cac0bd716e02c35adae36d..f811d76f6859ffe3cc4ebac23d39cfe9ca0d5a7e 100644 (file)
@@ -209,19 +209,17 @@ int rpc_samdump(int argc, const char **argv)
                return 1;
        }
 
-       if (!cli_nt_session_open(cli, PI_NETLOGON)) {
-               DEBUG(0,("Error connecting to NETLOGON pipe\n"));
-               goto fail;
-       }
+       fstrcpy(cli->domain, lp_workgroup());
 
-       if (!secrets_fetch_trust_account_password(lp_workgroup(), trust_password, NULL)) {
-               d_printf("Could not retrieve domain trust secret\n");
+       if (!secrets_fetch_trust_account_password(lp_workgroup(),
+                                                 trust_password,
+                                                 NULL)) {
+               DEBUG(0,("Could not fetch trust account password\n"));
                goto fail;
        }
-       
-       result = cli_nt_setup_creds(cli, SEC_CHAN_BDC,  trust_password, &neg_flags, 2);
-       if (!NT_STATUS_IS_OK(result)) {
-               d_printf("Failed to setup BDC creds\n");
+
+       if (!cli_nt_open_netlogon(cli, trust_password, SEC_CHAN_BDC)) {
+               DEBUG(0,("Error connecting to NETLOGON pipe\n"));
                goto fail;
        }