⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 changepw.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 1997 - 2005 Kungliga Tekniska H鰃skolan * (Royal Institute of Technology, Stockholm, Sweden).  * All rights reserved.  * * Redistribution and use in source and binary forms, with or without  * modification, are permitted provided that the following conditions  * are met:  * * 1. Redistributions of source code must retain the above copyright  *    notice, this list of conditions and the following disclaimer.  * * 2. Redistributions in binary form must reproduce the above copyright  *    notice, this list of conditions and the following disclaimer in the  *    documentation and/or other materials provided with the distribution.  * * 3. Neither the name of the Institute nor the names of its contributors  *    may be used to endorse or promote products derived from this software  *    without specific prior written permission.  * * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF  * SUCH DAMAGE.  */#include <krb5_locl.h>RCSID("$Id: changepw.c 21505 2007-07-12 12:28:38Z lha $");static voidstr2data (krb5_data *d,	  const char *fmt,	  ...) __attribute__ ((format (printf, 2, 3)));static voidstr2data (krb5_data *d,	  const char *fmt,	  ...){    va_list args;    char *str;    va_start(args, fmt);    d->length = vasprintf (&str, fmt, args);    va_end(args);    d->data = str;}/* * Change password protocol defined by * draft-ietf-cat-kerb-chg-password-02.txt *  * Share the response part of the protocol with MS set password * (RFC3244) */static krb5_error_codechgpw_send_request (krb5_context context,		    krb5_auth_context *auth_context,		    krb5_creds *creds,		    krb5_principal targprinc,		    int is_stream,		    int sock,		    const char *passwd,		    const char *host){    krb5_error_code ret;    krb5_data ap_req_data;    krb5_data krb_priv_data;    krb5_data passwd_data;    size_t len;    u_char header[6];    u_char *p;    struct iovec iov[3];    struct msghdr msghdr;    if (is_stream)	return KRB5_KPASSWD_MALFORMED;    if (targprinc &&	krb5_principal_compare(context, creds->client, targprinc) != TRUE)	return KRB5_KPASSWD_MALFORMED;    krb5_data_zero (&ap_req_data);    ret = krb5_mk_req_extended (context,				auth_context,				AP_OPTS_MUTUAL_REQUIRED | AP_OPTS_USE_SUBKEY,				NULL, /* in_data */				creds,				&ap_req_data);    if (ret)	return ret;    passwd_data.data   = rk_UNCONST(passwd);    passwd_data.length = strlen(passwd);    krb5_data_zero (&krb_priv_data);    ret = krb5_mk_priv (context,			*auth_context,			&passwd_data,			&krb_priv_data,			NULL);    if (ret)	goto out2;    len = 6 + ap_req_data.length + krb_priv_data.length;    p = header;    *p++ = (len >> 8) & 0xFF;    *p++ = (len >> 0) & 0xFF;    *p++ = 0;    *p++ = 1;    *p++ = (ap_req_data.length >> 8) & 0xFF;    *p++ = (ap_req_data.length >> 0) & 0xFF;    memset(&msghdr, 0, sizeof(msghdr));    msghdr.msg_name       = NULL;    msghdr.msg_namelen    = 0;    msghdr.msg_iov        = iov;    msghdr.msg_iovlen     = sizeof(iov)/sizeof(*iov);#if 0    msghdr.msg_control    = NULL;    msghdr.msg_controllen = 0;#endif    iov[0].iov_base    = (void*)header;    iov[0].iov_len     = 6;    iov[1].iov_base    = ap_req_data.data;    iov[1].iov_len     = ap_req_data.length;    iov[2].iov_base    = krb_priv_data.data;    iov[2].iov_len     = krb_priv_data.length;    if (sendmsg (sock, &msghdr, 0) < 0) {	ret = errno;	krb5_set_error_string(context, "sendmsg %s: %s", host, strerror(ret));    }    krb5_data_free (&krb_priv_data);out2:    krb5_data_free (&ap_req_data);    return ret;}/* * Set password protocol as defined by RFC3244 -- * Microsoft Windows 2000 Kerberos Change Password and Set Password Protocols */static krb5_error_codesetpw_send_request (krb5_context context,		    krb5_auth_context *auth_context,		    krb5_creds *creds,		    krb5_principal targprinc,		    int is_stream,		    int sock,		    const char *passwd,		    const char *host){    krb5_error_code ret;    krb5_data ap_req_data;    krb5_data krb_priv_data;    krb5_data pwd_data;    ChangePasswdDataMS chpw;    size_t len;    u_char header[4 + 6];    u_char *p;    struct iovec iov[3];    struct msghdr msghdr;    krb5_data_zero (&ap_req_data);    ret = krb5_mk_req_extended (context,				auth_context,				AP_OPTS_MUTUAL_REQUIRED | AP_OPTS_USE_SUBKEY,				NULL, /* in_data */				creds,				&ap_req_data);    if (ret)	return ret;    chpw.newpasswd.length = strlen(passwd);    chpw.newpasswd.data = rk_UNCONST(passwd);    if (targprinc) {	chpw.targname = &targprinc->name;	chpw.targrealm = &targprinc->realm;    } else {	chpw.targname = NULL;	chpw.targrealm = NULL;    }	    ASN1_MALLOC_ENCODE(ChangePasswdDataMS, pwd_data.data, pwd_data.length,		       &chpw, &len, ret);    if (ret) {	krb5_data_free (&ap_req_data);	return ret;    }    if(pwd_data.length != len)	krb5_abortx(context, "internal error in ASN.1 encoder");    ret = krb5_mk_priv (context,			*auth_context,			&pwd_data,			&krb_priv_data,			NULL);    if (ret)	goto out2;    len = 6 + ap_req_data.length + krb_priv_data.length;    p = header;    if (is_stream) {	_krb5_put_int(p, len, 4);	p += 4;    }    *p++ = (len >> 8) & 0xFF;    *p++ = (len >> 0) & 0xFF;    *p++ = 0xff;    *p++ = 0x80;    *p++ = (ap_req_data.length >> 8) & 0xFF;    *p++ = (ap_req_data.length >> 0) & 0xFF;    memset(&msghdr, 0, sizeof(msghdr));    msghdr.msg_name       = NULL;    msghdr.msg_namelen    = 0;    msghdr.msg_iov        = iov;    msghdr.msg_iovlen     = sizeof(iov)/sizeof(*iov);#if 0    msghdr.msg_control    = NULL;    msghdr.msg_controllen = 0;#endif    iov[0].iov_base    = (void*)header;    if (is_stream)	iov[0].iov_len     = 10;    else	iov[0].iov_len     = 6;    iov[1].iov_base    = ap_req_data.data;    iov[1].iov_len     = ap_req_data.length;    iov[2].iov_base    = krb_priv_data.data;    iov[2].iov_len     = krb_priv_data.length;    if (sendmsg (sock, &msghdr, 0) < 0) {	ret = errno;	krb5_set_error_string(context, "sendmsg %s: %s", host, strerror(ret));    }    krb5_data_free (&krb_priv_data);out2:    krb5_data_free (&ap_req_data);    krb5_data_free (&pwd_data);    return ret;}static krb5_error_codeprocess_reply (krb5_context context,	       krb5_auth_context auth_context,	       int is_stream,	       int sock,	       int *result_code,	       krb5_data *result_code_string,	       krb5_data *result_string,	       const char *host){    krb5_error_code ret;    u_char reply[1024 * 3];    ssize_t len;    uint16_t pkt_len, pkt_ver;    krb5_data ap_rep_data;    int save_errno;    len = 0;    if (is_stream) {	while (len < sizeof(reply)) {	    unsigned long size;	    ret = recvfrom (sock, reply + len, sizeof(reply) - len, 			    0, NULL, NULL);	    if (ret < 0) {		save_errno = errno;		krb5_set_error_string(context, "recvfrom %s: %s",				      host, strerror(save_errno));		return save_errno;	    } else if (ret == 0) {		krb5_set_error_string(context, "recvfrom timeout %s", host);		return 1;	    }	    len += ret;	    if (len < 4)		continue;	    _krb5_get_int(reply, &size, 4);	    if (size + 4 < len)		continue;	    memmove(reply, reply + 4, size);			    len = size;	    break;	}	if (len == sizeof(reply)) {	    krb5_set_error_string(context, "message too large from %s",				  host);	    return ENOMEM;	}    } else {	ret = recvfrom (sock, reply, sizeof(reply), 0, NULL, NULL);	if (ret < 0) {	    save_errno = errno;	    krb5_set_error_string(context, "recvfrom %s: %s",				  host, strerror(save_errno));	    return save_errno;	}	len = ret;    }    if (len < 6) {	str2data (result_string, "server %s sent to too short message "		  "(%ld bytes)", host, (long)len);	*result_code = KRB5_KPASSWD_MALFORMED;	return 0;    }    pkt_len = (reply[0] << 8) | (reply[1]);    pkt_ver = (reply[2] << 8) | (reply[3]);    if ((pkt_len != len) || (reply[1] == 0x7e || reply[1] == 0x5e)) {	KRB_ERROR error;	size_t size;	u_char *p;	memset(&error, 0, sizeof(error));	ret = decode_KRB_ERROR(reply, len, &error, &size);	if (ret)	    return ret;	if (error.e_data->length < 2) {	    str2data(result_string, "server %s sent too short "		     "e_data to print anything usable", host);	    free_KRB_ERROR(&error);	    *result_code = KRB5_KPASSWD_MALFORMED;	    return 0;	}	p = error.e_data->data;	*result_code = (p[0] << 8) | p[1];	if (error.e_data->length == 2)	    str2data(result_string, "server only sent error code");	else 	    krb5_data_copy (result_string,			    p + 2,			    error.e_data->length - 2);	free_KRB_ERROR(&error);	return 0;    }    if (pkt_len != len) {	str2data (result_string, "client: wrong len in reply");	*result_code = KRB5_KPASSWD_MALFORMED;	return 0;    }    if (pkt_ver != KRB5_KPASSWD_VERS_CHANGEPW) {	str2data (result_string,		  "client: wrong version number (%d)", pkt_ver);	*result_code = KRB5_KPASSWD_MALFORMED;	return 0;    }    ap_rep_data.data = reply + 6;    ap_rep_data.length  = (reply[4] << 8) | (reply[5]);      if (reply + len < (u_char *)ap_rep_data.data + ap_rep_data.length) {	str2data (result_string, "client: wrong AP len in reply");	*result_code = KRB5_KPASSWD_MALFORMED;	return 0;    }    if (ap_rep_data.length) {	krb5_ap_rep_enc_part *ap_rep;	krb5_data priv_data;	u_char *p;	priv_data.data   = (u_char*)ap_rep_data.data + ap_rep_data.length;	priv_data.length = len - ap_rep_data.length - 6;	ret = krb5_rd_rep (context,			   auth_context,			   &ap_rep_data,			   &ap_rep);	if (ret)	    return ret;	krb5_free_ap_rep_enc_part (context, ap_rep);	ret = krb5_rd_priv (context,			    auth_context,			    &priv_data,			    result_code_string,			    NULL);	if (ret) {	    krb5_data_free (result_code_string);	    return ret;	}	if (result_code_string->length < 2) {	    *result_code = KRB5_KPASSWD_MALFORMED;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -