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

📄 kpasswdd.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 2 页
字号:
			krb5_free_principal(context, principal);			return kpasswdd_make_error_reply(kdc, mem_ctx, 							KRB5_KPASSWD_MALFORMED,							"krb5_unparse_name failed!",							reply);		}				krb5_free_principal(context, principal);				samdb = samdb_connect(mem_ctx, kdc->task->event_ctx, kdc->task->lp_ctx, session_info);		if (!samdb) {			return kpasswdd_make_error_reply(kdc, mem_ctx, 							 KRB5_KPASSWD_HARDERROR,							 "Unable to open database!",							 reply);		}		DEBUG(3, ("%s\\%s (%s) is changing password of %s\n", 			  session_info->server_info->domain_name,			  session_info->server_info->account_name,			  dom_sid_string(mem_ctx, session_info->security_token->user_sid), 			  set_password_on_princ));		ret = ldb_transaction_start(samdb);		if (ret) {			status = NT_STATUS_TRANSACTION_ABORTED;			return kpasswd_make_pwchange_reply(kdc, mem_ctx, 							   status,							   SAMR_REJECT_OTHER, 							   NULL, 							   reply);		}		status = crack_user_principal_name(samdb, mem_ctx, 						   set_password_on_princ, 						   &set_password_on_dn, NULL);		free(set_password_on_princ);		if (!NT_STATUS_IS_OK(status)) {			ldb_transaction_cancel(samdb);			return kpasswd_make_pwchange_reply(kdc, mem_ctx, 							   status,							   SAMR_REJECT_OTHER, 							   NULL, 							   reply);		}		msg = ldb_msg_new(mem_ctx);		if (msg == NULL) {			ldb_transaction_cancel(samdb);			status = NT_STATUS_NO_MEMORY;		} else {			msg->dn = ldb_dn_copy(msg, set_password_on_dn);			if (!msg->dn) {				status = NT_STATUS_NO_MEMORY;			}		}		if (NT_STATUS_IS_OK(status)) {			/* Admin password set */			status = samdb_set_password(samdb, mem_ctx,						    set_password_on_dn, NULL,						    msg, password, NULL, NULL, 						    false, /* this is not a user password change */						    &reject_reason, &dominfo);		}		if (NT_STATUS_IS_OK(status)) {			/* modify the samdb record */			ret = samdb_replace(samdb, mem_ctx, msg);			if (ret != 0) {				DEBUG(2,("Failed to modify record to set password on %s: %s\n",					 ldb_dn_get_linearized(msg->dn),					 ldb_errstring(samdb)));				status = NT_STATUS_ACCESS_DENIED;			}		}		if (NT_STATUS_IS_OK(status)) {			ret = ldb_transaction_commit(samdb);			if (ret != 0) {				DEBUG(1,("Failed to commit transaction to set password on %s: %s\n",					 ldb_dn_get_linearized(msg->dn),					 ldb_errstring(samdb)));				status = NT_STATUS_TRANSACTION_ABORTED;			}		} else {			ldb_transaction_cancel(samdb);		}		return kpasswd_make_pwchange_reply(kdc, mem_ctx, 						   status,						   reject_reason, 						   dominfo, 						   reply);	}	default:		return kpasswdd_make_error_reply(kdc, mem_ctx, 						 KRB5_KPASSWD_BAD_VERSION,						 talloc_asprintf(mem_ctx, 								 "Protocol version %u not supported", 								 version),						 reply);	}	return true;}bool kpasswdd_process(struct kdc_server *kdc,		      TALLOC_CTX *mem_ctx, 		      DATA_BLOB *input, 		      DATA_BLOB *reply,		      struct socket_address *peer_addr,		      struct socket_address *my_addr,		      int datagram_reply){	bool ret;	const uint16_t header_len = 6;	uint16_t len;	uint16_t ap_req_len;	uint16_t krb_priv_len;	uint16_t version;	NTSTATUS nt_status;	DATA_BLOB ap_req, krb_priv_req;	DATA_BLOB krb_priv_rep = data_blob(NULL, 0);	DATA_BLOB ap_rep = data_blob(NULL, 0);	DATA_BLOB kpasswd_req, kpasswd_rep;	struct cli_credentials *server_credentials;	struct gensec_security *gensec_security;	TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);		if (!tmp_ctx) {		return false;	}	/* Be parinoid.  We need to ensure we don't just let the	 * caller lead us into a buffer overflow */	if (input->length <= header_len) {		talloc_free(tmp_ctx);		return false;	}	len = RSVAL(input->data, 0);	if (input->length != len) {		talloc_free(tmp_ctx);		return false;	}	/* There are two different versions of this protocol so far,	 * plus others in the standards pipe.  Fortunetly they all	 * take a very similar framing */	version = RSVAL(input->data, 2);	ap_req_len = RSVAL(input->data, 4);	if ((ap_req_len >= len) || (ap_req_len + header_len) >= len) {		talloc_free(tmp_ctx);		return false;	}		krb_priv_len = len - ap_req_len;	ap_req = data_blob_const(&input->data[header_len], ap_req_len);	krb_priv_req = data_blob_const(&input->data[header_len + ap_req_len], krb_priv_len);		nt_status = gensec_server_start(tmp_ctx, kdc->task->event_ctx, kdc->task->lp_ctx, kdc->task->msg_ctx, &gensec_security);	if (!NT_STATUS_IS_OK(nt_status)) {		talloc_free(tmp_ctx);		return false;	}	server_credentials = cli_credentials_init(tmp_ctx);	if (!server_credentials) {		DEBUG(1, ("Failed to init server credentials\n"));		return false;	}	/* We want the credentials subsystem to use the krb5 context	 * we already have, rather than a new context */		cli_credentials_set_krb5_context(server_credentials, kdc->smb_krb5_context);	cli_credentials_set_conf(server_credentials, kdc->task->lp_ctx);	nt_status = cli_credentials_set_stored_principal(server_credentials, kdc->task->event_ctx, kdc->task->lp_ctx, "kadmin/changepw");	if (!NT_STATUS_IS_OK(nt_status)) {		ret = kpasswdd_make_unauth_error_reply(kdc, mem_ctx, 						       KRB5_KPASSWD_HARDERROR,						       talloc_asprintf(mem_ctx, 								       "Failed to obtain server credentials for kadmin/changepw: %s\n", 								       nt_errstr(nt_status)),						       &krb_priv_rep);		ap_rep.length = 0;		if (ret) {			goto reply;		}		talloc_free(tmp_ctx);		return ret;	}		nt_status = gensec_set_credentials(gensec_security, server_credentials);	if (!NT_STATUS_IS_OK(nt_status)) {		talloc_free(tmp_ctx);		return false;	}	/* The kerberos PRIV packets include these addresses.  MIT	 * clients check that they are present */	nt_status = gensec_set_peer_addr(gensec_security, peer_addr);	if (!NT_STATUS_IS_OK(nt_status)) {		talloc_free(tmp_ctx);		return false;	}	nt_status = gensec_set_my_addr(gensec_security, my_addr);	if (!NT_STATUS_IS_OK(nt_status)) {		talloc_free(tmp_ctx);		return false;	}	/* We want the GENSEC wrap calls to generate PRIV tokens */	gensec_want_feature(gensec_security, GENSEC_FEATURE_SEAL);	nt_status = gensec_start_mech_by_name(gensec_security, "krb5");	if (!NT_STATUS_IS_OK(nt_status)) {		talloc_free(tmp_ctx);		return false;	}	/* Accept the AP-REQ and generate teh AP-REP we need for the reply */	nt_status = gensec_update(gensec_security, tmp_ctx, ap_req, &ap_rep);	if (!NT_STATUS_IS_OK(nt_status) && !NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {				ret = kpasswdd_make_unauth_error_reply(kdc, mem_ctx, 						       KRB5_KPASSWD_HARDERROR,						       talloc_asprintf(mem_ctx, 								       "gensec_update failed: %s", 								       nt_errstr(nt_status)),						       &krb_priv_rep);		ap_rep.length = 0;		if (ret) {			goto reply;		}		talloc_free(tmp_ctx);		return ret;	}	/* Extract the data from the KRB-PRIV half of the message */	nt_status = gensec_unwrap(gensec_security, tmp_ctx, &krb_priv_req, &kpasswd_req);	if (!NT_STATUS_IS_OK(nt_status)) {		ret = kpasswdd_make_unauth_error_reply(kdc, mem_ctx, 						       KRB5_KPASSWD_HARDERROR,						       talloc_asprintf(mem_ctx, 								       "gensec_unwrap failed: %s", 								       nt_errstr(nt_status)),						       &krb_priv_rep);		ap_rep.length = 0;		if (ret) {			goto reply;		}		talloc_free(tmp_ctx);		return ret;	}	/* Figure out something to do with it (probably changing a password...) */	ret = kpasswd_process_request(kdc, tmp_ctx, 				      gensec_security, 				      version, 				      &kpasswd_req, &kpasswd_rep); 	if (!ret) {		/* Argh! */		return false;	}	/* And wrap up the reply: This ensures that the error message	 * or success can be verified by the client */	nt_status = gensec_wrap(gensec_security, tmp_ctx, 				&kpasswd_rep, &krb_priv_rep);	if (!NT_STATUS_IS_OK(nt_status)) {		ret = kpasswdd_make_unauth_error_reply(kdc, mem_ctx, 						       KRB5_KPASSWD_HARDERROR,						       talloc_asprintf(mem_ctx, 								       "gensec_wrap failed: %s", 								       nt_errstr(nt_status)),						       &krb_priv_rep);		ap_rep.length = 0;		if (ret) {			goto reply;		}		talloc_free(tmp_ctx);		return ret;	}	reply:	*reply = data_blob_talloc(mem_ctx, NULL, krb_priv_rep.length + ap_rep.length + header_len);	if (!reply->data) {		return false;	}	RSSVAL(reply->data, 0, reply->length);	RSSVAL(reply->data, 2, 1); /* This is a version 1 reply, MS change/set or otherwise */	RSSVAL(reply->data, 4, ap_rep.length);	memcpy(reply->data + header_len, 	       ap_rep.data, 	       ap_rep.length);	memcpy(reply->data + header_len + ap_rep.length, 	       krb_priv_rep.data, 	       krb_priv_rep.length);	talloc_free(tmp_ctx);	return ret;}

⌨️ 快捷键说明

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