first pass at updating head branch to be to be the same as the SAMBA_2_0 branch
[kai/samba.git] / source3 / rpc_client / cli_netlogon.c
index 757c5166e884ae988d8cf775ee1d555312a01b24..8202960089354403df06142408017691d255b84a 100644 (file)
@@ -30,6 +30,7 @@
 #include "includes.h"
 
 extern int DEBUGLEVEL;
+extern pstring scope;
 extern pstring global_myname;
 extern fstring global_myworkgroup;
 
@@ -64,8 +65,8 @@ BOOL cli_net_logon_ctrl2(struct cli_state *cli, uint32 status_level)
   NET_Q_LOGON_CTRL2 q_l;
   BOOL ok = False;
 
-  prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
-  prs_init(&rbuf, 0,    4, SAFETY_MARGIN, True );
+  prs_init(&buf , 1024, 4, False);
+  prs_init(&rbuf, 0,    4, True );
 
   /* create and send a MSRPC command with api NET_LOGON_CTRL2 */
 
@@ -73,18 +74,25 @@ BOOL cli_net_logon_ctrl2(struct cli_state *cli, uint32 status_level)
            global_myname, status_level));
 
   /* store the parameters */
-  make_q_logon_ctrl2(&q_l, cli->srv_name_slash, status_level);
+  init_q_logon_ctrl2(&q_l, cli->srv_name_slash, status_level);
 
   /* turn parameters into data stream */
-  net_io_q_logon_ctrl2("", &q_l,  &buf, 0);
+  if(!net_io_q_logon_ctrl2("", &q_l,  &buf, 0)) {
+    DEBUG(0,("cli_net_logon_ctrl2: Error : failed to marshall NET_Q_LOGON_CTRL2 struct.\n"));
+    prs_mem_free(&buf);
+    prs_mem_free(&rbuf);
+    return False;
+  }
 
   /* send the data on \PIPE\ */
   if (rpc_api_pipe_req(cli, NET_LOGON_CTRL2, &buf, &rbuf))
   {
     NET_R_LOGON_CTRL2 r_l;
 
-    net_io_r_logon_ctrl2("", &r_l, &rbuf, 0);
-    ok = (rbuf.offset != 0);
+    /*
+     * Unmarshall the return buffer.
+     */
+    ok = net_io_r_logon_ctrl2("", &r_l, &rbuf, 0);
                
     if (ok && r_l.status != 0)
     {
@@ -95,8 +103,8 @@ BOOL cli_net_logon_ctrl2(struct cli_state *cli, uint32 status_level)
     }
   }
 
+  prs_mem_free(&buf);
   prs_mem_free(&rbuf);
-  prs_mem_free(&buf );
 
   return ok;
 }
@@ -118,8 +126,8 @@ BOOL cli_net_auth2(struct cli_state *cli, uint16 sec_chan,
   NET_Q_AUTH_2 q_a;
   BOOL ok = False;
 
-  prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
-  prs_init(&rbuf, 0,    4, SAFETY_MARGIN, True );
+  prs_init(&buf , 1024, 4, False);
+  prs_init(&rbuf, 0,    4, True );
 
   /* create and send a MSRPC command with api NET_AUTH2 */
 
@@ -128,19 +136,23 @@ BOOL cli_net_auth2(struct cli_state *cli, uint16 sec_chan,
          credstr(cli->clnt_cred.challenge.data), neg_flags));
 
   /* store the parameters */
-  make_q_auth_2(&q_a, cli->srv_name_slash, cli->mach_acct, sec_chan, global_myname,
+  init_q_auth_2(&q_a, cli->srv_name_slash, cli->mach_acct, sec_chan, global_myname,
                 &cli->clnt_cred.challenge, neg_flags);
 
   /* turn parameters into data stream */
-  net_io_q_auth_2("", &q_a,  &buf, 0);
+  if(!net_io_q_auth_2("", &q_a,  &buf, 0)) {
+    DEBUG(0,("cli_net_auth2: Error : failed to marshall NET_Q_AUTH_2 struct.\n"));
+    prs_mem_free(&buf);
+    prs_mem_free(&rbuf);
+    return False;
+  }
 
   /* send the data on \PIPE\ */
   if (rpc_api_pipe_req(cli, NET_AUTH2, &buf, &rbuf))
   {
     NET_R_AUTH_2 r_a;
 
-    net_io_r_auth_2("", &r_a, &rbuf, 0);
-    ok = (rbuf.offset != 0);
+    ok = net_io_r_auth_2("", &r_a, &rbuf, 0);
                
     if (ok && r_a.status != 0)
     {
@@ -169,6 +181,12 @@ password ?).\n", cli->desthost ));
       }
     }
 
+#if 0
+    /*
+     * Try commenting this out to see if this makes the connect
+     * work for a NT 3.51 PDC. JRA.
+     */
+
     if (ok && r_a.srv_flgs.neg_flags != q_a.clnt_flgs.neg_flags)
     {
       /* report different neg_flags */
@@ -176,11 +194,12 @@ password ?).\n", cli->desthost ));
           q_a.clnt_flgs.neg_flags, r_a.srv_flgs.neg_flags));
       ok = False;
     }
+#endif
 
   }
 
+  prs_mem_free(&buf);
   prs_mem_free(&rbuf);
-  prs_mem_free(&buf );
 
   return ok;
 }
@@ -197,11 +216,8 @@ BOOL cli_net_req_chal(struct cli_state *cli, DOM_CHAL *clnt_chal, DOM_CHAL *srv_
   NET_Q_REQ_CHAL q_c;
   BOOL valid_chal = False;
 
-  if (srv_chal == NULL || clnt_chal == NULL)
-    return False;
-
-  prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
-  prs_init(&rbuf, 0,    4, SAFETY_MARGIN, True );
+  prs_init(&buf , 1024, 4, False);
+  prs_init(&rbuf, 0,    4, True );
 
   /* create and send a MSRPC command with api NET_REQCHAL */
 
@@ -209,10 +225,15 @@ BOOL cli_net_req_chal(struct cli_state *cli, DOM_CHAL *clnt_chal, DOM_CHAL *srv_
          cli->desthost, global_myname, credstr(clnt_chal->data)));
 
   /* store the parameters */
-  make_q_req_chal(&q_c, cli->srv_name_slash, global_myname, clnt_chal);
+  init_q_req_chal(&q_c, cli->srv_name_slash, global_myname, clnt_chal);
 
   /* turn parameters into data stream */
-  net_io_q_req_chal("", &q_c,  &buf, 0);
+  if(!net_io_q_req_chal("", &q_c,  &buf, 0)) {
+    DEBUG(0,("cli_net_req_chal: Error : failed to marshall NET_Q_REQ_CHAL struct.\n"));
+    prs_mem_free(&buf);
+    prs_mem_free(&rbuf);
+    return False;
+  }
 
   /* send the data on \PIPE\ */
   if (rpc_api_pipe_req(cli, NET_REQCHAL, &buf, &rbuf))
@@ -220,8 +241,7 @@ BOOL cli_net_req_chal(struct cli_state *cli, DOM_CHAL *clnt_chal, DOM_CHAL *srv_
     NET_R_REQ_CHAL r_c;
     BOOL ok;
 
-    net_io_r_req_chal("", &r_c, &rbuf, 0);
-    ok = (rbuf.offset != 0);
+    ok = net_io_r_req_chal("", &r_c, &rbuf, 0);
                
     if (ok && r_c.status != 0)
     {
@@ -239,8 +259,8 @@ BOOL cli_net_req_chal(struct cli_state *cli, DOM_CHAL *clnt_chal, DOM_CHAL *srv_
     }
   }
 
+  prs_mem_free(&buf);
   prs_mem_free(&rbuf);
-  prs_mem_free(&buf );
 
   return valid_chal;
 }
@@ -260,8 +280,8 @@ BOOL cli_net_srv_pwset(struct cli_state *cli, uint8 hashed_mach_pwd[16])
 
   gen_next_creds( cli, &new_clnt_cred);
 
-  prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
-  prs_init(&rbuf, 0,    4, SAFETY_MARGIN, True );
+  prs_init(&buf , 1024, 4, False);
+  prs_init(&rbuf, 0,    4, True );
 
   /* create and send a MSRPC command with api NET_SRV_PWSET */
 
@@ -270,19 +290,23 @@ BOOL cli_net_srv_pwset(struct cli_state *cli, uint8 hashed_mach_pwd[16])
            credstr(new_clnt_cred.challenge.data), new_clnt_cred.timestamp.time));
 
   /* store the parameters */
-  make_q_srv_pwset(&q_s, cli->srv_name_slash, cli->mach_acct, sec_chan_type,
+  init_q_srv_pwset(&q_s, cli->srv_name_slash, cli->mach_acct, sec_chan_type,
                    global_myname, &new_clnt_cred, (char *)hashed_mach_pwd);
 
   /* turn parameters into data stream */
-  net_io_q_srv_pwset("", &q_s,  &buf, 0);
+  if(!net_io_q_srv_pwset("", &q_s,  &buf, 0)) {
+    DEBUG(0,("cli_net_srv_pwset: Error : failed to marshall NET_Q_SRV_PWSET struct.\n"));
+    prs_mem_free(&buf);
+    prs_mem_free(&rbuf);
+    return False;
+  }
 
   /* send the data on \PIPE\ */
   if (rpc_api_pipe_req(cli, NET_SRVPWSET, &buf, &rbuf))
   {
     NET_R_SRV_PWSET r_s;
 
-    net_io_r_srv_pwset("", &r_s, &rbuf, 0);
-    ok = (rbuf.offset != 0);
+    ok = net_io_r_srv_pwset("", &r_s, &rbuf, 0);
                
     if (ok && r_s.status != 0)
     {
@@ -304,8 +328,8 @@ password ?).\n", cli->desthost ));
     }
   }
 
+  prs_mem_free(&buf);
   prs_mem_free(&rbuf);
-  prs_mem_free(&buf );
 
   return ok;
 }
@@ -327,8 +351,8 @@ BOOL cli_net_sam_logon(struct cli_state *cli, NET_ID_INFO_CTR *ctr,
 
   gen_next_creds( cli, &new_clnt_cred);
 
-  prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
-  prs_init(&rbuf, 0,    4, SAFETY_MARGIN, True );
+  prs_init(&buf , 1024, 4, False);
+  prs_init(&rbuf, 0,    4, True );
 
   /* create and send a MSRPC command with api NET_SAMLOGON */
 
@@ -338,13 +362,20 @@ BOOL cli_net_sam_logon(struct cli_state *cli, NET_ID_INFO_CTR *ctr,
              ctr->switch_value));
 
   memset(&dummy_rtn_creds, '\0', sizeof(dummy_rtn_creds));
+       dummy_rtn_creds.timestamp.time = time(NULL);
 
   /* store the parameters */
-  make_sam_info(&(q_s.sam_id), cli->srv_name_slash, global_myname,
-         &new_clnt_cred, &dummy_rtn_creds, ctr->switch_value, ctr, validation_level);
+  q_s.validation_level = validation_level;
+  init_sam_info(&q_s.sam_id, cli->srv_name_slash, global_myname,
+         &new_clnt_cred, &dummy_rtn_creds, ctr->switch_value, ctr);
 
   /* turn parameters into data stream */
-  net_io_q_sam_logon("", &q_s,  &buf, 0);
+  if(!net_io_q_sam_logon("", &q_s,  &buf, 0)) {
+    DEBUG(0,("cli_net_sam_logon: Error : failed to marshall NET_Q_SAM_LOGON struct.\n"));
+    prs_mem_free(&buf);
+    prs_mem_free(&rbuf);
+    return False;
+  }
 
   /* send the data on \PIPE\ */
   if (rpc_api_pipe_req(cli, NET_SAMLOGON, &buf, &rbuf))
@@ -353,8 +384,7 @@ BOOL cli_net_sam_logon(struct cli_state *cli, NET_ID_INFO_CTR *ctr,
 
     r_s.user = user_info3;
 
-    net_io_r_sam_logon("", &r_s, &rbuf, 0);
-    ok = (rbuf.offset != 0);
+    ok = net_io_r_sam_logon("", &r_s, &rbuf, 0);
                
     if (ok && r_s.status != 0)
     {
@@ -384,13 +414,12 @@ password ?).\n", cli->desthost ));
     }
   }
 
+  prs_mem_free(&buf);
   prs_mem_free(&rbuf);
-  prs_mem_free(&buf );
 
   return ok;
 }
 
-#if UNUSED_CODE
 /***************************************************************************
 LSA SAM Logoff.
 
@@ -407,13 +436,12 @@ BOOL cli_net_sam_logoff(struct cli_state *cli, NET_ID_INFO_CTR *ctr)
   prs_struct rbuf;
   prs_struct buf; 
   NET_Q_SAM_LOGOFF q_s;
-  uint16 validation_level = 3;
   BOOL ok = False;
 
   gen_next_creds( cli, &new_clnt_cred);
 
-  prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
-  prs_init(&rbuf, 0,    4, SAFETY_MARGIN, True );
+  prs_init(&buf , 1024, 4, False);
+  prs_init(&rbuf, 0,    4, True );
 
   /* create and send a MSRPC command with api NET_SAMLOGOFF */
 
@@ -424,20 +452,23 @@ BOOL cli_net_sam_logoff(struct cli_state *cli, NET_ID_INFO_CTR *ctr)
 
   memset(&dummy_rtn_creds, '\0', sizeof(dummy_rtn_creds));
 
-  /* store the parameters */
-  make_sam_info(&(q_s.sam_id), cli->srv_name_slash, global_myname,
-                &new_clnt_cred, &dummy_rtn_creds, ctr->switch_value, ctr, validation_level);
+  init_sam_info(&q_s.sam_id, cli->srv_name_slash, global_myname,
+                &new_clnt_cred, &dummy_rtn_creds, ctr->switch_value, ctr);
 
   /* turn parameters into data stream */
-  net_io_q_sam_logoff("", &q_s,  &buf, 0);
+  if(!net_io_q_sam_logoff("", &q_s,  &buf, 0)) {
+    DEBUG(0,("cli_net_sam_logoff: Error : failed to marshall NET_Q_SAM_LOGOFF struct.\n"));
+    prs_mem_free(&buf);
+    prs_mem_free(&rbuf);
+    return False;
+  }
 
   /* send the data on \PIPE\ */
   if (rpc_api_pipe_req(cli, NET_SAMLOGOFF, &buf, &rbuf))
   {
     NET_R_SAM_LOGOFF r_s;
 
-    net_io_r_sam_logoff("", &r_s, &rbuf, 0);
-    ok = (rbuf.offset != 0);
+    ok = net_io_r_sam_logoff("", &r_s, &rbuf, 0);
                
     if (ok && r_s.status != 0)
     {
@@ -459,12 +490,11 @@ password ?).\n", cli->desthost ));
     }
   }
 
+  prs_mem_free(&buf);
   prs_mem_free(&rbuf);
-  prs_mem_free(&buf );
 
   return ok;
 }
-#endif
 
 /*********************************************************
  Change the domain password on the PDC.
@@ -474,7 +504,6 @@ static BOOL modify_trust_password( char *domain, char *remote_machine,
                           unsigned char orig_trust_passwd_hash[16],
                           unsigned char new_trust_passwd_hash[16])
 {
-  struct in_addr dest_ip;
   struct cli_state cli;
 
   ZERO_STRUCT(cli);
@@ -483,27 +512,26 @@ static BOOL modify_trust_password( char *domain, char *remote_machine,
     return False;
   }
 
-  if(!resolve_name( remote_machine, &dest_ip)) {
+  if(!resolve_name( remote_machine, &cli.dest_ip, 0x20)) {
     DEBUG(0,("modify_trust_password: Can't resolve address for %s\n", remote_machine));
     return False;
   }
 
-  if (ismyip(dest_ip)) {
+  if (ismyip(cli.dest_ip)) {
     DEBUG(0,("modify_trust_password: Machine %s is one of our addresses. Cannot add \
 to ourselves.\n", remote_machine));
     return False;
   }
 
-  if (!cli_connect(&cli, remote_machine, &dest_ip)) {
+  if (!cli_connect(&cli, remote_machine, &cli.dest_ip)) {
     DEBUG(0,("modify_trust_password: unable to connect to SMB server on \
 machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
     return False;
   }
-    
-  if (!cli_session_request(&cli, remote_machine, 0x20, global_myname)) {
-    DEBUG(0,("modify_trust_password: machine %s rejected the session setup. \
-Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
-    cli_shutdown(&cli);
+  
+  if (!attempt_netbios_session_request(&cli, global_myname, remote_machine, &cli.dest_ip)) {
+    DEBUG(0,("modify_trust_password: machine %s rejected the NetBIOS \
+session request. Error was %s\n", remote_machine, cli_errstr(&cli) ));
     return False;
   }
 
@@ -515,6 +543,7 @@ Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
     cli_shutdown(&cli);
     return False;
   }
+
   if (cli.protocol != PROTOCOL_NT1) {
     DEBUG(0,("modify_trust_password: machine %s didn't negotiate NT protocol.\n", 
             remote_machine));
@@ -552,7 +581,7 @@ Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
    * Now start the NT Domain stuff :-).
    */
     
-  if(cli_nt_session_open(&cli, PIPE_NETLOGON, False) == False) {
+  if(cli_nt_session_open(&cli, PIPE_NETLOGON) == False) {
     DEBUG(0,("modify_trust_password: unable to open the domain client session to \
 machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli)));
     cli_nt_session_close(&cli);
@@ -599,6 +628,7 @@ BOOL change_trust_account_password( char *domain, char *remote_machine_list)
   unsigned char old_trust_passwd_hash[16];
   unsigned char new_trust_passwd_hash[16];
   time_t lct;
+  BOOL res;
 
   if(!get_trust_account_password( old_trust_passwd_hash, &lct)) {
     DEBUG(0,("change_trust_account_password: unable to read the machine \
@@ -615,19 +645,59 @@ account password for domain %s.\n", domain));
        next_token(&remote_machine_list, remote_machine, 
                   LIST_SEP, sizeof(remote_machine))) {
     strupper(remote_machine);
-    if(modify_trust_password( domain, remote_machine, 
-                              old_trust_passwd_hash, new_trust_passwd_hash)) {
+    if(strequal(remote_machine, "*")) {
+
+      /*
+       * We have been asked to dynamcially determine the IP addresses of the PDC.
+       */
+
+      struct in_addr *ip_list = NULL;
+      int count = 0;
+      int i;
+
+      if(!get_dc_list(domain, &ip_list, &count))
+        continue;
+
+      /*
+       * Try and connect to the PDC/BDC list in turn as an IP
+       * address used as a string.
+       */
+
+      for(i = 0; i < count; i++) {
+        fstring dc_name;
+        if(!lookup_pdc_name(global_myname, domain, &ip_list[i], dc_name))
+          continue;
+        if((res = modify_trust_password( domain, dc_name,
+                                         old_trust_passwd_hash, new_trust_passwd_hash)))
+          break;
+      }
+
+      if(ip_list != NULL)
+        free((char *)ip_list);
+
+    } else {
+      res = modify_trust_password( domain, remote_machine,
+                                   old_trust_passwd_hash, new_trust_passwd_hash);
+    }
+
+    if(res) {
       DEBUG(0,("%s : change_trust_account_password: Changed password for \
-domain %s.\n", timestring(), domain));
+domain %s.\n", timestring(False), domain));
       /*
        * Return the result of trying to write the new password
        * back into the trust account file.
        */
-      return set_trust_account_password(new_trust_passwd_hash);
+      res = set_trust_account_password(new_trust_passwd_hash);
+      memset(new_trust_passwd_hash, 0, 16);
+      memset(old_trust_passwd_hash, 0, 16);
+      return res;
     }
   }
 
+  memset(new_trust_passwd_hash, 0, 16);
+  memset(old_trust_passwd_hash, 0, 16);
+
   DEBUG(0,("%s : change_trust_account_password: Failed to change password for \
-domain %s.\n", timestring(), domain));
+domain %s.\n", timestring(False), domain));
   return False;
 }