[1753] in Moira

home help back first fref pref prev next nref lref last post

changes to setpw.c

daemon@ATHENA.MIT.EDU (David E. Tanner)
Mon Mar 19 16:19:13 2001

Message-Id: <3.0.32.20010319161528.0119d008@po14.mit.edu>
Date: Mon, 19 Mar 2001 16:15:29 -0500
To: moiradev@MIT.EDU
From: "David E. Tanner" <dtanner@MIT.EDU>
Mime-Version: 1.0
Content-Type: text/enriched; charset="us-ascii"

<smaller>Below are changes that I had to make to the set password
processing for the WIN2K KDC.  There is also some code cleanup.


Index: setpw.c

===================================================================

RCS file:
/afs/athena.mit.edu/astaff/project/moiradev/repository/moira/incremental/winad/setpw.c,v

retrieving revision 1.1

diff -c -r1.1 setpw.c

*** setpw.c	2000/11/11 11:05:49	1.1

--- setpw.c	2001/03/19 19:58:21

***************

*** 359,366 ****

    int               tmp_len;

    int               error_count;

    krb5_principal    targprinc;

!   struct timeval    TimeVal;

!   fd_set            readfds;

  

    auth_context = NULL;

    addr_p = NULL;

--- 359,366 ----

    int               tmp_len;

    int               error_count;

    krb5_principal    targprinc;

!   int               count;

!   int               last_count;

  

    auth_context = NULL;

    addr_p = NULL;

***************

*** 401,422 ****

        goto cleanup;

      }

  

-   /* this is really obscure.  s1 is used for all communications.  it

-      is left unconnected in case the server is multihomed and routes

-      are asymmetric.  s2 is connected to resolve routes and get

-      addresses.  this is the *only* way to get proper addresses for

-      multihomed hosts if routing is asymmetric.  

- 

-      A related problem in the server, but not the client, is that

-      many os's have no way to disconnect a connected udp socket, so

-      the s2 socket needs to be closed and recreated for each

-      request.  The s1 socket must not be closed, or else queued

-      requests will be lost.

- 

-      A "naive" client implementation (one socket, no connect,

-      hostname resolution to get the local ip addr) will work and

-      interoperate if the client is single-homed. */

- 

    if ((s1 = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET)

      {

        free(addr_p);

--- 401,406 ----

***************

*** 433,439 ****

      {

  	    if (connect(s2, &addr_p[i], sizeof(addr_p[i])) == SOCKET_ERROR)

          continue;

- 

  	    addrlen = sizeof(local_addr);

      	if (getsockname(s2, &local_addr, &addrlen) << 0)

          continue;

--- 417,422 ----

***************

*** 465,492 ****

  	      sizeof(((struct sockaddr_in *) &remote_addr)->sin_addr);

  	    remote_kaddr.contents = 

  	      (char *) &(((struct sockaddr_in *) &remote_addr)->sin_addr);

! 	    /* mk_priv requires that the local address be set.

! 	       getsockname is used for this.  rd_priv requires that the

! 	       remote address be set.  recvfrom is used for this.  If

! 	       rd_priv is given a local address, and the message has the

! 	       recipient addr in it, this will be checked.  However, there

! 	       is simply no way to know ahead of time what address the

! 	       message will be delivered *to*.  Therefore, it is important

! 	       that either no recipient address is in the messages when

! 	       mk_priv is called, or that no local address is passed to

! 	       rd_priv.  Both is a better idea, and I have done that.  In

! 	       summary, when mk_priv is called, *only* a local address is

! 	       specified.  when rd_priv is called, *only* a remote address

! 	       is specified.  Are we having fun yet?  */

  	    if (code = krb5_auth_con_setaddrs(context, auth_context,
&local_kaddr, NULL))

          goto cleanup;

  	    if (code = krb5_mk_setpw_req(context, auth_context, &ap_req,

  			                            targprinc, newpw, &chpw_req))

          goto cleanup;

  	    if ((cc = sendto(s1, chpw_req.data, chpw_req.length, 0,

  			                 (struct sockaddr *) &addr_p[i],

  			                 sizeof(addr_p[i]))) != chpw_req.length)

!         continue; /* try the next addr */

  #ifdef _WIN32

        krb5_free_data_contents(context, &chpw_req);

  #else

--- 448,465 ----

  	      sizeof(((struct sockaddr_in *) &remote_addr)->sin_addr);

  	    remote_kaddr.contents = 

  	      (char *) &(((struct sockaddr_in *) &remote_addr)->sin_addr);

! 

  	    if (code = krb5_auth_con_setaddrs(context, auth_context,
&local_kaddr, NULL))

          goto cleanup;

  	    if (code = krb5_mk_setpw_req(context, auth_context, &ap_req,

  			                            targprinc, newpw, &chpw_req))

          goto cleanup;

+ 

  	    if ((cc = sendto(s1, chpw_req.data, chpw_req.length, 0,

  			                 (struct sockaddr *) &addr_p[i],

  			                 sizeof(addr_p[i]))) != chpw_req.length)

!         continue;

! 

  #ifdef _WIN32

        krb5_free_data_contents(context, &chpw_req);

  #else

***************

*** 494,532 ****

  #endif

  	    chpw_rep.length = 1500;

  	    chpw_rep.data = (char *) calloc(1, chpw_rep.length);

-     	/* XXX need a timeout/retry loop here */

- 	    /* "recv" would be good enough here... except that Windows/NT

- 	       commits the atrocity of returning -1 to indicate failure,

- 	       but leaving errno set to 0.

- 	   

- 	       "recvfrom(...,NULL,NULL)" would seem to be a good enough

- 	       alternative, and it works on NT, but it doesn't work on

- 	       SunOS 4.1.4 or Irix 5.3.  Thus we must actually accept the

- 	       value and discard it. */

- 	    tmp_len = sizeof(tmp_addr);

-       TimeVal.tv_sec = 10;

-       TimeVal.tv_usec = 0;

  

!       FD_ZERO(&readfds);

!       FD_SET(s1, &readfds);

!       code = select(1, &readfds, NULL, NULL, &TimeVal);

! 

!       if ((code == 0) || (code == SOCKET_ERROR))

!         {

!           if (error_count << 2)

!             {

!               closesocket(s1);

!               closesocket(s2);

!               if ((s1 = socket(AF_INET, SOCK_DGRAM, 0)) ==
INVALID_SOCKET)

!                 goto cleanup;

!               if ((s2 = socket(AF_INET, SOCK_DGRAM, 0)) ==
INVALID_SOCKET)

!                 goto cleanup;

!               ++error_count;

!               --i;

!               continue;

!             }

!           code = errno;

!           goto cleanup;

          }

  	    if ((cc = recvfrom(s1, chpw_rep.data, chpw_rep.length, 0,
&tmp_addr, &tmp_len)) << 0)

          {

--- 467,488 ----

  #endif

  	    chpw_rep.length = 1500;

  	    chpw_rep.data = (char *) calloc(1, chpw_rep.length);

  

! 	    tmp_len = sizeof(tmp_addr);

!       last_count = 0;

!       while (1)

!         {

!         cc = recvfrom(s1, chpw_rep.data, chpw_rep.length, MSG_PEEK,
&tmp_addr, &tmp_len);

!         if ((last_count == cc) && (cc != 0))

!           break;

!         last_count = cc;

!         if (cc == 0)

!           {

!           if (last_count == -1)

!             break;

!           last_count = -1;

!           }

!         sleep(1);

          }

  	    if ((cc = recvfrom(s1, chpw_rep.data, chpw_rep.length, 0,
&tmp_addr, &tmp_len)) << 0)

          {

***************

*** 543,554 ****

  	    code = krb5_rd_setpw_rep(context, auth_context, &chpw_rep,

  			                         &local_result_code, &result_string);

  

! 	    if (result_code)

! 	      *result_code = local_result_code;

  #ifdef _WIN32

!       krb5_free_data_contents(context, &chpw_req);

  #else

!       free(chpw_req.data);

  #endif

        break;

  

--- 499,514 ----

  	    code = krb5_rd_setpw_rep(context, auth_context, &chpw_rep,

  			                         &local_result_code, &result_string);

  

! 	    if (local_result_code)

!         {

!           if (local_result_code == KRB5_KPASSWD_SOFTERROR)

!             local_result_code = KRB5_KPASSWD_SUCCESS;

!   	      *result_code = local_result_code;

!         }

  #ifdef _WIN32

!       krb5_free_data_contents(context, &chpw_rep);

  #else

!       free(chpw_rep.data);

  #endif

        break;

  

***************

*** 589,599 ****

  

    memset(pw, '\0', sizeof(pw));

    generate_password(pw);

    retval = krb5_set_password(context, ccache, pw, user, domain,
&res_code);

  

  	krb5_cc_close(context, ccache);

  	krb5_free_context(context);

!   return(retval);

  }

  

  void generate_password(char *password)

--- 549,562 ----

  

    memset(pw, '\0', sizeof(pw));

    generate_password(pw);

+   res_code = 0;

    retval = krb5_set_password(context, ccache, pw, user, domain,
&res_code);

  

  	krb5_cc_close(context, ccache);

  	krb5_free_context(context);

!   if (retval)

!     return(retval);

!   return(res_code);

  }

  

  void generate_password(char *password)


</smaller>

home help back first fref pref prev next nref lref last post