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

📄 init_creds_pw.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (c) 1997 - 2007 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: init_creds_pw.c 21931 2007-08-27 14:11:55Z lha $");typedef struct krb5_get_init_creds_ctx {    KDCOptions flags;    krb5_creds cred;    krb5_addresses *addrs;    krb5_enctype *etypes;    krb5_preauthtype *pre_auth_types;    const char *in_tkt_service;    unsigned nonce;    unsigned pk_nonce;    krb5_data req_buffer;    AS_REQ as_req;    int pa_counter;    const char *password;    krb5_s2k_proc key_proc;    krb5_get_init_creds_tristate req_pac;    krb5_pk_init_ctx pk_init_ctx;    int ic_flags;} krb5_get_init_creds_ctx;static krb5_error_codedefault_s2k_func(krb5_context context, krb5_enctype type, 		 krb5_const_pointer keyseed,		 krb5_salt salt, krb5_data *s2kparms,		 krb5_keyblock **key){    krb5_error_code ret;    krb5_data password;    krb5_data opaque;    password.data = rk_UNCONST(keyseed);    password.length = strlen(keyseed);    if (s2kparms)	opaque = *s2kparms;    else	krb5_data_zero(&opaque);	    *key = malloc(sizeof(**key));    if (*key == NULL)	return ENOMEM;    ret = krb5_string_to_key_data_salt_opaque(context, type, password,					      salt, opaque, *key);    if (ret) {	free(*key);	*key = NULL;    }    return ret;}static voidfree_init_creds_ctx(krb5_context context, krb5_get_init_creds_ctx *ctx){    if (ctx->etypes)	free(ctx->etypes);    if (ctx->pre_auth_types)	free (ctx->pre_auth_types);    free_AS_REQ(&ctx->as_req);    memset(&ctx->as_req, 0, sizeof(ctx->as_req));}static intget_config_time (krb5_context context,		 const char *realm,		 const char *name,		 int def){    int ret;    ret = krb5_config_get_time (context, NULL,				"realms",				realm,				name,				NULL);    if (ret >= 0)	return ret;    ret = krb5_config_get_time (context, NULL,				"libdefaults",				name,				NULL);    if (ret >= 0)	return ret;    return def;}static krb5_error_codeinit_cred (krb5_context context,	   krb5_creds *cred,	   krb5_principal client,	   krb5_deltat start_time,	   const char *in_tkt_service,	   krb5_get_init_creds_opt *options){    krb5_error_code ret;    krb5_const_realm client_realm;    int tmp;    krb5_timestamp now;    krb5_timeofday (context, &now);    memset (cred, 0, sizeof(*cred));        if (client)	krb5_copy_principal(context, client, &cred->client);    else {	ret = krb5_get_default_principal (context,					  &cred->client);	if (ret)	    goto out;    }    client_realm = krb5_principal_get_realm (context, cred->client);    if (start_time)	cred->times.starttime  = now + start_time;    if (options->flags & KRB5_GET_INIT_CREDS_OPT_TKT_LIFE)	tmp = options->tkt_life;    else	tmp = 10 * 60 * 60;    cred->times.endtime = now + tmp;    if ((options->flags & KRB5_GET_INIT_CREDS_OPT_RENEW_LIFE) &&	options->renew_life > 0) {	cred->times.renew_till = now + options->renew_life;    }    if (in_tkt_service) {	krb5_realm server_realm;	ret = krb5_parse_name (context, in_tkt_service, &cred->server);	if (ret)	    goto out;	server_realm = strdup (client_realm);	free (*krb5_princ_realm(context, cred->server));	krb5_princ_set_realm (context, cred->server, &server_realm);    } else {	ret = krb5_make_principal(context, &cred->server, 				  client_realm, KRB5_TGS_NAME, client_realm,				  NULL);	if (ret)	    goto out;    }    return 0;out:    krb5_free_cred_contents (context, cred);    return ret;}/* * Print a message (str) to the user about the expiration in `lr' */static voidreport_expiration (krb5_context context,		   krb5_prompter_fct prompter,		   krb5_data *data,		   const char *str,		   time_t now){    char *p;	        asprintf (&p, "%s%s", str, ctime(&now));    (*prompter) (context, data, NULL, p, 0, NULL);    free (p);}/* * Parse the last_req data and show it to the user if it's interesting */static voidprint_expire (krb5_context context,	      krb5_const_realm realm,	      krb5_kdc_rep *rep,	      krb5_prompter_fct prompter,	      krb5_data *data){    int i;    LastReq *lr = &rep->enc_part.last_req;    krb5_timestamp sec;    time_t t;    krb5_boolean reported = FALSE;    krb5_timeofday (context, &sec);    t = sec + get_config_time (context,			       realm,			       "warn_pwexpire",			       7 * 24 * 60 * 60);    for (i = 0; i < lr->len; ++i) {	if (lr->val[i].lr_value <= t) {	    switch (abs(lr->val[i].lr_type)) {	    case LR_PW_EXPTIME :		report_expiration(context, prompter, data,				  "Your password will expire at ",				  lr->val[i].lr_value);		reported = TRUE;		break;	    case LR_ACCT_EXPTIME :		report_expiration(context, prompter, data,				  "Your account will expire at ",				  lr->val[i].lr_value);		reported = TRUE;		break;	    }	}    }    if (!reported	&& rep->enc_part.key_expiration	&& *rep->enc_part.key_expiration <= t) {	report_expiration(context, prompter, data,			  "Your password/account will expire at ",			  *rep->enc_part.key_expiration);    }}static krb5_addresses no_addrs = { 0, NULL };static krb5_error_codeget_init_creds_common(krb5_context context,		      krb5_principal client,		      krb5_deltat start_time,		      const char *in_tkt_service,		      krb5_get_init_creds_opt *options,		      krb5_get_init_creds_ctx *ctx){    krb5_get_init_creds_opt default_opt;    krb5_error_code ret;    krb5_enctype *etypes;    krb5_preauthtype *pre_auth_types;    memset(ctx, 0, sizeof(*ctx));    if (options == NULL) {	krb5_get_init_creds_opt_init (&default_opt);	options = &default_opt;    } else {	_krb5_get_init_creds_opt_free_krb5_error(options);    }    if (options->opt_private) {	ctx->password = options->opt_private->password;	ctx->key_proc = options->opt_private->key_proc;	ctx->req_pac = options->opt_private->req_pac;	ctx->pk_init_ctx = options->opt_private->pk_init_ctx;	ctx->ic_flags = options->opt_private->flags;    } else	ctx->req_pac = KRB5_INIT_CREDS_TRISTATE_UNSET;    if (ctx->key_proc == NULL)	ctx->key_proc = default_s2k_func;    if (ctx->ic_flags & KRB5_INIT_CREDS_CANONICALIZE)	ctx->flags.canonicalize = 1;    ctx->pre_auth_types = NULL;    ctx->addrs = NULL;    ctx->etypes = NULL;    ctx->pre_auth_types = NULL;    ctx->in_tkt_service = in_tkt_service;    ret = init_cred (context, &ctx->cred, client, start_time,		     in_tkt_service, options);    if (ret)	return ret;    if (options->flags & KRB5_GET_INIT_CREDS_OPT_FORWARDABLE)	ctx->flags.forwardable = options->forwardable;    if (options->flags & KRB5_GET_INIT_CREDS_OPT_PROXIABLE)	ctx->flags.proxiable = options->proxiable;    if (start_time)	ctx->flags.postdated = 1;    if (ctx->cred.times.renew_till)	ctx->flags.renewable = 1;    if (options->flags & KRB5_GET_INIT_CREDS_OPT_ADDRESS_LIST) {	ctx->addrs = options->address_list;    } else if (options->opt_private) {	switch (options->opt_private->addressless) {	case KRB5_INIT_CREDS_TRISTATE_UNSET:#if KRB5_ADDRESSLESS_DEFAULT == TRUE	    ctx->addrs = &no_addrs;#else	    ctx->addrs = NULL;#endif	    break;	case KRB5_INIT_CREDS_TRISTATE_FALSE:	    ctx->addrs = NULL;	    break;	case KRB5_INIT_CREDS_TRISTATE_TRUE:	    ctx->addrs = &no_addrs;	    break;	}    }    if (options->flags & KRB5_GET_INIT_CREDS_OPT_ETYPE_LIST) {	etypes = malloc((options->etype_list_length + 1)			* sizeof(krb5_enctype));	if (etypes == NULL) {	    krb5_set_error_string(context, "malloc: out of memory");	    return ENOMEM;	}	memcpy (etypes, options->etype_list,		options->etype_list_length * sizeof(krb5_enctype));	etypes[options->etype_list_length] = ETYPE_NULL;	ctx->etypes = etypes;    }    if (options->flags & KRB5_GET_INIT_CREDS_OPT_PREAUTH_LIST) {	pre_auth_types = malloc((options->preauth_list_length + 1)				* sizeof(krb5_preauthtype));	if (pre_auth_types == NULL) {	    krb5_set_error_string(context, "malloc: out of memory");	    return ENOMEM;	}	memcpy (pre_auth_types, options->preauth_list,		options->preauth_list_length * sizeof(krb5_preauthtype));	pre_auth_types[options->preauth_list_length] = KRB5_PADATA_NONE;	ctx->pre_auth_types = pre_auth_types;    }    if (options->flags & KRB5_GET_INIT_CREDS_OPT_SALT)	;			/* XXX */    if (options->flags & KRB5_GET_INIT_CREDS_OPT_ANONYMOUS)	ctx->flags.request_anonymous = options->anonymous;    return 0;}static krb5_error_codechange_password (krb5_context context,		 krb5_principal client,		 const char *password,		 char *newpw,		 size_t newpw_sz,		 krb5_prompter_fct prompter,		 void *data,		 krb5_get_init_creds_opt *old_options){    krb5_prompt prompts[2];    krb5_error_code ret;    krb5_creds cpw_cred;    char buf1[BUFSIZ], buf2[BUFSIZ];    krb5_data password_data[2];    int result_code;    krb5_data result_code_string;    krb5_data result_string;    char *p;    krb5_get_init_creds_opt options;    memset (&cpw_cred, 0, sizeof(cpw_cred));    krb5_get_init_creds_opt_init (&options);    krb5_get_init_creds_opt_set_tkt_life (&options, 60);    krb5_get_init_creds_opt_set_forwardable (&options, FALSE);    krb5_get_init_creds_opt_set_proxiable (&options, FALSE);    if (old_options && old_options->flags & KRB5_GET_INIT_CREDS_OPT_PREAUTH_LIST)	krb5_get_init_creds_opt_set_preauth_list (&options,						  old_options->preauth_list,						  old_options->preauth_list_length);					          krb5_data_zero (&result_code_string);    krb5_data_zero (&result_string);    ret = krb5_get_init_creds_password (context,					&cpw_cred,					client,					password,					prompter,					data,					0,					"kadmin/changepw",					&options);    if (ret)	goto out;    for(;;) {	password_data[0].data   = buf1;	password_data[0].length = sizeof(buf1);	prompts[0].hidden = 1;	prompts[0].prompt = "New password: ";	prompts[0].reply  = &password_data[0];	prompts[0].type   = KRB5_PROMPT_TYPE_NEW_PASSWORD;	password_data[1].data   = buf2;	password_data[1].length = sizeof(buf2);	prompts[1].hidden = 1;	prompts[1].prompt = "Repeat new password: ";	prompts[1].reply  = &password_data[1];	prompts[1].type   = KRB5_PROMPT_TYPE_NEW_PASSWORD_AGAIN;	ret = (*prompter) (context, data, NULL, "Changing password",			   2, prompts);	if (ret) {	    memset (buf1, 0, sizeof(buf1));	    memset (buf2, 0, sizeof(buf2));	    goto out;	}	if (strcmp (buf1, buf2) == 0)	    break;	memset (buf1, 0, sizeof(buf1));	memset (buf2, 0, sizeof(buf2));    }        ret = krb5_change_password (context,				&cpw_cred,				buf1,				&result_code,				&result_code_string,				&result_string);    if (ret)	goto out;    asprintf (&p, "%s: %.*s\n",	      result_code ? "Error" : "Success",	      (int)result_string.length,	      result_string.length > 0 ? (char*)result_string.data : "");    ret = (*prompter) (context, data, NULL, p, 0, NULL);    free (p);    if (result_code == 0) {	strlcpy (newpw, buf1, newpw_sz);	ret = 0;    } else {	krb5_set_error_string (context, "failed changing password");	ret = ENOTTY;    }out:    memset (buf1, 0, sizeof(buf1));    memset (buf2, 0, sizeof(buf2));    krb5_data_free (&result_string);    krb5_data_free (&result_code_string);    krb5_free_cred_contents (context, &cpw_cred);    return ret;}krb5_error_code KRB5_LIB_FUNCTIONkrb5_keyblock_key_proc (krb5_context context,			krb5_keytype type,			krb5_data *salt,			krb5_const_pointer keyseed,			krb5_keyblock **key){    return krb5_copy_keyblock (context, keyseed, key);}krb5_error_code KRB5_LIB_FUNCTIONkrb5_get_init_creds_keytab(krb5_context context,			   krb5_creds *creds,			   krb5_principal client,			   krb5_keytab keytab,			   krb5_deltat start_time,			   const char *in_tkt_service,			   krb5_get_init_creds_opt *options){    krb5_get_init_creds_ctx ctx;    krb5_error_code ret;    krb5_keytab_key_proc_args *a;        ret = get_init_creds_common(context, client, start_time,				in_tkt_service, options, &ctx);    if (ret)	goto out;    a = malloc (sizeof(*a));    if (a == NULL) {	krb5_set_error_string(context, "malloc: out of memory");	ret = ENOMEM;	goto out;    }    a->principal = ctx.cred.client;    a->keytab    = keytab;    ret = krb5_get_in_cred (context,			    KDCOptions2int(ctx.flags),			    ctx.addrs,			    ctx.etypes,			    ctx.pre_auth_types,			    NULL,			    krb5_keytab_key_proc,			    a,			    NULL,			    NULL,			    &ctx.cred,			    NULL);    free (a);    if (ret == 0 && creds)	*creds = ctx.cred;    else	krb5_free_cred_contents (context, &ctx.cred); out:    free_init_creds_ctx(context, &ctx);    return ret;}/* * */static krb5_error_codeinit_creds_init_as_req (krb5_context context,			KDCOptions opts,			const krb5_creds *creds,			const krb5_addresses *addrs,			const krb5_enctype *etypes,			AS_REQ *a){    krb5_error_code ret;

⌨️ 快捷键说明

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