[prev in list] [next in list] [prev in thread] [next in thread] 

List:       pecl-cvs
Subject:    [PECL-CVS] =?utf-8?q?svn:_/pecl/krb5/tags/_krb5-1.1.0/trunk/CREDITS_krb5-1.1.0/trunk/INSTALL_krb5-1.
From:       Moritz_Bechler <mbechler () php ! net>
Date:       2016-07-16 14:46:31
Message-ID: svn-mbechler-1468680391-339676-1242496621 () svn ! php ! net
[Download RAW message or body]

mbechler                                 Sat, 16 Jul 2016 14:46:31 +0000

Revision: http://svn.php.net/viewvc?view=revision&revision=339676

Log:
Tagging the 1.1.0 release

Changed paths:
<changed paths exceeded maximum size>


["svn-diffs-339676.txt" (text/x-diff)]

Copied: pecl/krb5/tags/krb5-1.1.0/trunk/CREDITS (from rev 339675, \
pecl/krb5/trunk/CREDITS) \
                ===================================================================
--- pecl/krb5/tags/krb5-1.1.0/trunk/CREDITS	                        (rev 0)
+++ pecl/krb5/tags/krb5-1.1.0/trunk/CREDITS	2016-07-16 14:46:31 UTC (rev 339676)
@@ -0,0 +1,2 @@
+;; krb5
+Moritz Bechler [mbechler] <mbechler@eenterphace.org> (lead)

Copied: pecl/krb5/tags/krb5-1.1.0/trunk/INSTALL (from rev 339675, \
pecl/krb5/trunk/INSTALL) \
                ===================================================================
--- pecl/krb5/tags/krb5-1.1.0/trunk/INSTALL	                        (rev 0)
+++ pecl/krb5/tags/krb5-1.1.0/trunk/INSTALL	2016-07-16 14:46:31 UTC (rev 339676)
@@ -0,0 +1,14 @@
+Installation:
++ When compiling this extension as shared module:
+  - run phpize in the extension directory
+  - run ./configure (optionally add --with-krb5kadm if you need this functionality)
+  - run make && make install
+  - optional: enable your new extension in you php.ini
+
++ When compiling statically into your php binary
+  - move this extension into your php distributions ext/ folder
+  - make sure that the directory is named "krb5"
+  - run ./buildconf --force in the root directory of you php distribution
+  - ./configure php with your common flags and add --with-krb5 and optionally
+  	--with-krb5kadm=<path>
+  - make && make install

Copied: pecl/krb5/tags/krb5-1.1.0/trunk/LICENSE (from rev 339675, \
pecl/krb5/trunk/LICENSE) \
                ===================================================================
--- pecl/krb5/tags/krb5-1.1.0/trunk/LICENSE	                        (rev 0)
+++ pecl/krb5/tags/krb5-1.1.0/trunk/LICENSE	2016-07-16 14:46:31 UTC (rev 339676)
@@ -0,0 +1,19 @@
+Copyright (c) 2008 Moritz Bechler
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.

Copied: pecl/krb5/tags/krb5-1.1.0/trunk/README (from rev 339675, \
pecl/krb5/trunk/README) \
                ===================================================================
--- pecl/krb5/tags/krb5-1.1.0/trunk/README	                        (rev 0)
+++ pecl/krb5/tags/krb5-1.1.0/trunk/README	2016-07-16 14:46:31 UTC (rev 339676)
@@ -0,0 +1,13 @@
+Kerberos, GSSAPI and KADM5 bindings
+
+Features:
++ An interface for maintaining credential caches (KRB5CCache),
+   that can be used for authenticating against a kerberos5 realm
++ Bindings for nearly the complete GSSAPI (RFC2744)
++ The administrative interface (KADM5)
++ Support for HTTP Negotiate authentication via GSSAPI
+
+Documentation:
++ see docs/ for the API documentation
++ there are several pieces of example code in the examples/ directory
++ see below for install instructions

Copied: pecl/krb5/tags/krb5-1.1.0/trunk/compat.h (from rev 339675, \
pecl/krb5/trunk/compat.h) \
                ===================================================================
--- pecl/krb5/tags/krb5-1.1.0/trunk/compat.h	                        (rev 0)
+++ pecl/krb5/tags/krb5-1.1.0/trunk/compat.h	2016-07-16 14:46:31 UTC (rev 339676)
@@ -0,0 +1,245 @@
+#ifndef PHP_KRB5_COMPAT_H
+#define PHP_KRB5_COMPAT_H
+
+
+#if PHP_MAJOR_VERSION < 7
+struct _zend_string {
+	char *val;
+	int   len;
+	int   persistent;
+};
+typedef struct _zend_string zend_string;
+typedef long zend_long;
+typedef int strsize_t;
+
+static zend_always_inline zend_string *zend_string_alloc(int len, int persistent)
+{
+	/* single alloc, so free the buf, will also free the struct */
+	char *buf = safe_pemalloc(sizeof(zend_string)+len+1,1,0,persistent);
+	zend_string *str = (zend_string *)(buf+len+1);
+
+	str->val = buf;
+	str->len = len;
+	str->persistent = persistent;
+
+	return str;
+}
+
+static zend_always_inline zend_string *zend_string_init(char *s, int len, int \
persistent) { +	/* single alloc, so free the buf, will also free the struct */
+	char *buf = safe_pemalloc(sizeof(zend_string)+len+1,1,0,persistent);
+	zend_string *str = (zend_string *)(buf+len+1);
+
+	str->val = buf;
+	str->len = len;
+	str->persistent = persistent;
+
+	memcpy(str->val, s, len);
+
+	return str;
+}
+
+static zend_always_inline void zend_string_free(zend_string *s)
+{
+	pefree(s->val, s->persistent);
+}
+
+
+static zend_always_inline void zend_string_release(zend_string *s)
+{
+	zend_string_free(s);
+}
+/* compatibility macros */
+#define _RETURN_STRING(a)      RETURN_STRING(a,1)
+/* new macros */
+#define RETURN_NEW_STR(s)     RETURN_STRINGL(s->val,s->len,0);
+#define ZVAL_DEREF(z)
+
+#define Z_ISNULL_P(z) (z == NULL)
+
+#define _ZVAL_STRINGL(a,b,c) ZVAL_STRINGL(a,b,c,1)
+#define _ZVAL_STRING(a,b) ZVAL_STRING(a,b,1)
+#define _RETVAL_STRINGL(a,b) RETVAL_STRINGL(a,b,1)
+#define _RETVAL_STRING(a) RETVAL_STRING(a,1)
+
+#define _DECLARE_ZVAL(name) zval * name = NULL
+#define _INIT_ZVAL INIT_ZVAL
+#define _ALLOC_INIT_ZVAL(name) ALLOC_INIT_ZVAL(name)
+#define _RELEASE_ZVAL(name) zval_ptr_dtor(&name)
+#define _add_next_index_string(...) add_next_index_string(__VA_ARGS__, 1)
+#define _add_assoc_string(...) add_assoc_string(__VA_ARGS__, 1)
+#define _add_assoc_string_ex(...) add_assoc_string_ex(__VA_ARGS__, 1)
+#define _add_assoc_stringl_ex(...) add_assoc_stringl_ex(__VA_ARGS__, 1)
+
+//#define Z_OBJCE_P(zv) zend_get_class_entry(zv TSRMLS_CC)
+
+static inline long zval_get_long(zval *zv TSRMLS_DC) {
+	zval* copy;
+	long val;
+	MAKE_STD_ZVAL(copy);
+	MAKE_COPY_ZVAL(&zv, copy);
+	convert_to_long(copy);
+	val = Z_LVAL_P(copy);
+	zval_ptr_dtor(&copy);
+	return val;
+}
+
+static inline zend_string *zval_get_string(zval *zv TSRMLS_DC) {
+	zval* copy;
+	zend_string *val;
+	MAKE_STD_ZVAL(copy);
+	MAKE_COPY_ZVAL(&zv, copy);
+	convert_to_string(copy);
+	val = zend_string_init(Z_STRVAL_P(copy), Z_STRLEN_P(copy)+1, 0);
+	val->val[Z_STRLEN_P(copy)] = 0;
+	zval_ptr_dtor(&copy);
+	return val;
+}
+
+#define KRB5_CCACHE(zv) (krb5_ccache_object *) zend_object_store_get_object(zv \
TSRMLS_CC) +#define KRB5_NEGOTIATE_AUTH(zv) (krb5_negotiate_auth_object *) \
zend_object_store_get_object(zv TSRMLS_CC) +#define KRB5_GSSAPI_CONTEXT(zv) \
(krb5_gssapi_context_object *) zend_object_store_get_object(zv TSRMLS_CC) +
+
+#define KRB5_KADM(zv) (krb5_kadm5_object*)zend_object_store_get_object(zv TSRMLS_CC)
+#define KRB5_KADM_POLICY(zv) \
(krb5_kadm5_policy_object*)zend_object_store_get_object(zv TSRMLS_CC) +#define \
KRB5_KADM_PRINCIPAL(zv) (krb5_kadm5_principal_object*)zend_object_store_get_object(zv \
TSRMLS_CC) +#define KRB5_KADM_TLDATA(zv) \
(krb5_kadm5_tldata_object*)zend_object_store_get_object(zv TSRMLS_CC) +
+
+#else
+#include "zend_operators.h"
+
+typedef size_t strsize_t;
+/* removed/uneeded macros */
+#define TSRMLS_CC
+/* compatibility macros */
+#define _RETURN_STRING(a)      RETURN_STRING(a)
+
+#define _DECLARE_ZVAL(name) zval name ## _v; zval * name = &name ## _v
+#define _ALLOC_INIT_ZVAL(name) ZVAL_NULL(name)
+#define _RELEASE_ZVAL(name) zval_ptr_dtor(name)
+#define _add_next_index_string add_next_index_string
+#define _add_assoc_string(z, k, s) add_assoc_string_ex(z, k, strlen(k)+1, s)
+#define _add_assoc_string_ex add_assoc_string_ex
+#define _add_assoc_stringl_ex add_assoc_stringl_ex
+
+#define _ZVAL_STRINGL(a,b,c) ZVAL_STRINGL(a,b,c)
+#define _ZVAL_STRING(a,b) ZVAL_STRING(a,b)
+#define _RETVAL_STRINGL(a,b) RETVAL_STRINGL(a,b)
+#define _RETVAL_STRING(a) RETVAL_STRING(a)
+
+#define KRB5_CCACHE(zv) (krb5_ccache_object*)((char *)Z_OBJ_P(zv) - \
XtOffsetOf(krb5_ccache_object, std)) +#define KRB5_NEGOTIATE_AUTH(zv)  \
(krb5_negotiate_auth_object*)((char *)Z_OBJ_P(zv) - \
XtOffsetOf(krb5_negotiate_auth_object, std)) +#define KRB5_GSSAPI_CONTEXT(zv)  \
(krb5_gssapi_context_object*)((char *)Z_OBJ_P(zv) - \
XtOffsetOf(krb5_gssapi_context_object, std)) +
+#define KRB5_KADM(zv) (krb5_kadm5_object*)((char *)Z_OBJ_P(zv) - \
XtOffsetOf(krb5_kadm5_object, std)) +#define KRB5_KADM_POLICY(zv) \
(krb5_kadm5_policy_object*)((char *)Z_OBJ_P(zv) - \
XtOffsetOf(krb5_kadm5_policy_object, std)) +#define KRB5_KADM_PRINCIPAL(zv) \
(krb5_kadm5_principal_object*)((char *)Z_OBJ_P(zv) - \
XtOffsetOf(krb5_kadm5_principal_object, std)) +#define KRB5_KADM_TLDATA(zv) \
(krb5_kadm5_tldata_object*)((char *)Z_OBJ_P(zv) - \
XtOffsetOf(krb5_kadm5_tldata_object, std)) +
+#endif
+
+static zend_always_inline zval* zend_compat_hash_index_find(HashTable *ht, \
zend_ulong idx) +{
+#if PHP_MAJOR_VERSION < 7
+	zval **tmp, *result;
+
+	if (zend_hash_index_find(ht, idx, (void **) &tmp) == FAILURE) {
+		return NULL;
+	}
+
+	result = *tmp;
+	return result;
+#else
+	return zend_hash_index_find(ht, idx);
+#endif
+}
+
+static zend_always_inline zval* zend_compat_hash_find(HashTable *ht, char *key, \
size_t len) +{
+#if PHP_MAJOR_VERSION < 7
+	zval **tmp;
+	if (zend_hash_find(ht, key, len, (void **) &tmp) == FAILURE) {
+		return NULL;
+	}
+	return *tmp;
+#else
+	zval *result;
+	zend_string *key_str = zend_string_init(key, len-1, 0);
+	result = zend_hash_find(ht, key_str);
+	zend_string_release(key_str);
+	return result;
+#endif
+}
+
+#define KRB5_THIS_CCACHE KRB5_CCACHE(getThis())
+#define KRB5_THIS_NEGOTIATE_AUTH KRB5_NEGOTIATE_AUTH(getThis())
+#define KRB5_THIS_GSSAPI_CONTEXT KRB5_GSSAPI_CONTEXT(getThis())
+
+#define KRB5_THIS_KADM KRB5_KADM(getThis())
+#define KRB5_THIS_KADM_POLICY KRB5_KADM_POLICY(getThis())
+#define KRB5_THIS_KADM_PRINCIPAL KRB5_KADM_PRINCIPAL(getThis())
+#define KRB5_THIS_KADM_TLDATA KRB5_KADM_TLDATA(getThis())
+
+
+
+
+/* PHP Compatability */
+#if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION == 1 && PHP_RELEASE_VERSION > 2) || \
(PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 1) || (PHP_MAJOR_VERSION > 5) +
+#define INIT_STD_OBJECT(object, ce) zend_object_std_init(&(object), ce TSRMLS_CC);
+
+#else
+
+#define INIT_STD_OBJECT(object, ce) \
+	{ 	\
+		ALLOC_HASHTABLE(object.properties); \
+		zend_hash_init(object.properties,0, NULL, ZVAL_PTR_DTOR, 0); \
+		object.ce = ce; \
+		object.guards = NULL; \
+	}
+
+#endif
+
+
+#if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION == 1 && PHP_RELEASE_VERSION > 2) || \
(PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 1) || (PHP_MAJOR_VERSION > 5) +#define \
OBJECT_STD_DTOR(object) zend_object_std_dtor(&(object) TSRMLS_CC); +#else
+#define OBJECT_STD_DTOR(object) \
+	{ 	\
+		if(object.guards) { \
+			zend_hash_destroy(object.guards); \
+			FREE_HASHTABLE(object.guards); \
+		} \
+		if(object.properties) { \
+			zend_hash_destroy(object.properties); \
+			FREE_HASHTABLE(object.properties); \
+		} \
+	}
+#endif
+
+#if defined(PHP_VERSION_ID) && PHP_VERSION_ID >= 50400
+#define ARG_PATH "p"
+#else
+#define ARG_PATH "s"
+#endif
+
+#if defined(PHP_VERSION_ID) && PHP_VERSION_ID >= 50300
+/* php_set_error_handling() is deprecated */
+#define KRB5_SET_ERROR_HANDLING(type)  zend_replace_error_handling(type, NULL, NULL \
TSRMLS_CC) +#else
+#define KRB5_SET_ERROR_HANDLING(type)  php_set_error_handling(type, NULL  TSRMLS_CC)
+#endif
+
+/* For PHP < 5.3 */
+#ifndef zend_parse_parameters_none
+#define zend_parse_parameters_none() zend_parse_parameters(ZEND_NUM_ARGS() \
TSRMLS_CC, "") +#endif
+
+/* For PHP < 5.3 */
+#ifndef PHP_FE_END
+#define PHP_FE_END {NULL, NULL, NULL}
+#endif
+
+#endif

Copied: pecl/krb5/tags/krb5-1.1.0/trunk/config.m4 (from rev 339675, \
pecl/krb5/trunk/config.m4) \
                ===================================================================
--- pecl/krb5/tags/krb5-1.1.0/trunk/config.m4	                        (rev 0)
+++ pecl/krb5/tags/krb5-1.1.0/trunk/config.m4	2016-07-16 14:46:31 UTC (rev 339676)
@@ -0,0 +1,66 @@
+PHP_ARG_WITH(krb5, for kerberos support,
+ [  --with-krb5             Include generic kerberos5/GSSAPI support]
+ )
+
+PHP_ARG_WITH(krb5config, path to krb5config tool,
+ [  --with-krb5config       Path to krb5config tool],
+ no, no
+ )
+
+PHP_ARG_WITH(krb5kadm, for kerberos KADM5 support,
+ [  --with-krb5kadm[=S]      Include KADM5 Kerberos Administration Support - MIT \
only], + no, no
+ )
+
+if test "$PHP_KRB5" != "no" -o "$PHP_KRB5KADM" != "no"; then
+
+
+	if test "$PHP_KRB5CONFIG" == "no"; then
+		PHP_KRB5CONFIG=`which krb5-config`
+	fi
+
+	AC_MSG_CHECKING([whether we have krb5config])
+
+	if test -x $PHP_KRB5CONFIG; then
+		AC_MSG_RESULT($PHP_KRB5CONFIG)
+	else
+		AC_MSG_ERROR([no])
+		exit
+	fi
+
+
+
+	if test "$PHP_KRB5KADM" != "no"; then
+		KRB5_LDFLAGS=`$PHP_KRB5CONFIG --libs krb5 gssapi kadm-client`
+		KRB5_CFLAGS=`$PHP_KRB5CONFIG --cflags krb5 gssapi kadm-client`
+	else
+		KRB5_LDFLAGS=`$PHP_KRB5CONFIG --libs krb5 gssapi`
+		KRB5_CFLAGS=`$PHP_KRB5CONFIG --cflags krb5 gssapi`
+	fi
+
+	AC_MSG_CHECKING([for required linker flags])
+	AC_MSG_RESULT($KRB5_LDFLAGS)
+
+	AC_MSG_CHECKING([for required compiler flags])
+	AC_MSG_RESULT($KRB5_CFLAGS)
+
+	KRB5_VERSION=`$PHP_KRB5CONFIG --version`
+
+	AC_MSG_CHECKING([for kerberos library version])
+	AC_MSG_RESULT($KRB5_VERSION)
+	AC_DEFINE_UNQUOTED(KRB5_VERSION, ["$KRB5_VERSION"], [Kerberos library version])
+
+	SOURCE_FILES="krb5.c negotiate_auth.c gssapi.c"
+
+	if test "$PHP_KRB5KADM" != "no"; then
+		SOURCE_FILES="${SOURCE_FILES} kadm.c kadm5_principal.c kadm5_policy.c \
kadm5_tldata.c" +		AC_DEFINE(HAVE_KADM5, [], [Enable KADM5 support])
+	fi
+
+	CFLAGS="-Wall ${CFLAGS} ${KRB5_CFLAGS}"
+	LDFLAGS="${LDFLAGS} ${KRB5_LDFLAGS}"
+	PHP_SUBST(CFLAGS)
+	PHP_SUBST(LDFLAGS)
+	PHP_NEW_EXTENSION(krb5, $SOURCE_FILES, $ext_shared)
+	PHP_INSTALL_HEADERS([ext/krb5], [php_krb5.h])
+fi

Copied: pecl/krb5/tags/krb5-1.1.0/trunk/examples/kadm/ex1.php (from rev 339675, \
pecl/krb5/trunk/examples/kadm/ex1.php) \
                ===================================================================
--- pecl/krb5/tags/krb5-1.1.0/trunk/examples/kadm/ex1.php	                        \
                (rev 0)
+++ pecl/krb5/tags/krb5-1.1.0/trunk/examples/kadm/ex1.php	2016-07-16 14:46:31 UTC \
(rev 339676) @@ -0,0 +1,44 @@
+<?php
+
+$ticket = new KRB5CCache();
+$ticket->initPassword('test', 'foobar');
+var_dump($ticket);
+
+$ticket2 = new KRB5CCache();
+$ticket2->initKeytab('test2', 'test.keytab');
+var_dump($ticket2);
+
+
+$conn = new KADM5('test2/admin', 'test.keytab', true);
+
+$princ = new KADM5Principal("test");
+var_dump($princ);
+
+try {
+	var_dump($princ->changePassword('footest'));
+	die("A password change on a new entry succeeded");
+} catch (Exception $e) {
+}
+
+echo "\nListing prinicpals:\n";
+
+foreach($conn->getPrincipals() as $princ) {
+	echo " +  $princ\n";
+}
+
+
+echo "\nGet principal testuser\n";
+$princ2 = $conn->getPrincipal('testuser');
+var_dump($princ2);
+var_dump($princ2->load());
+var_dump($princ2);
+
+
+
+try {
+var_dump($princ2->changePassword('fooobar'));
+} catch(Exception $e) {
+
+}
+
+?>

Copied: pecl/krb5/tags/krb5-1.1.0/trunk/examples/kadm/ex2.php (from rev 339675, \
pecl/krb5/trunk/examples/kadm/ex2.php) \
                ===================================================================
--- pecl/krb5/tags/krb5-1.1.0/trunk/examples/kadm/ex2.php	                        \
                (rev 0)
+++ pecl/krb5/tags/krb5-1.1.0/trunk/examples/kadm/ex2.php	2016-07-16 14:46:31 UTC \
(rev 339676) @@ -0,0 +1,9 @@
+<?php
+
+$conn = new KADM5('test2/admin', 'test.keytab', true);
+$princ = $conn->getPrincipal('test');
+var_dump($princ->getPropertyArray());
+$princ->setExpiryTime(time() + 60*60*24*100);
+$princ->save();
+echo "\n";
+?>

Copied: pecl/krb5/tags/krb5-1.1.0/trunk/examples/kadm/ex3.php (from rev 339675, \
pecl/krb5/trunk/examples/kadm/ex3.php) \
                ===================================================================
--- pecl/krb5/tags/krb5-1.1.0/trunk/examples/kadm/ex3.php	                        \
                (rev 0)
+++ pecl/krb5/tags/krb5-1.1.0/trunk/examples/kadm/ex3.php	2016-07-16 14:46:31 UTC \
(rev 339676) @@ -0,0 +1,27 @@
+<?php
+$conn = new KADM5('test2/admin', 'test.keytab', true);
+
+
+$princ = new KADM5Principal('testlala');
+var_dump($princ->getName());
+try {
+	$exists = $conn->getPrincipal('testlala');
+	$exists->delete();
+} catch ( Exception $e ) {
+	echo $e;
+}
+
+$princ->setExpiryTime(2342342);
+$conn->createPrincipal($princ, 'testpass');
+
+var_dump($princ);
+var_dump($princ->getPropertyArray());
+
+$princ->resetFailedAuthCount();
+$princ->save();
+
+$princ->delete();
+
+unset($princ);
+
+?>

Copied: pecl/krb5/tags/krb5-1.1.0/trunk/examples/kadm/ex4.php (from rev 339675, \
pecl/krb5/trunk/examples/kadm/ex4.php) \
                ===================================================================
--- pecl/krb5/tags/krb5-1.1.0/trunk/examples/kadm/ex4.php	                        \
                (rev 0)
+++ pecl/krb5/tags/krb5-1.1.0/trunk/examples/kadm/ex4.php	2016-07-16 14:46:31 UTC \
(rev 339676) @@ -0,0 +1,57 @@
+<?php
+$conn = new KADM5('test2/admin', 'test.keytab', true);
+
+$policy = null;
+try {
+	$policy = $conn->getPolicy('some');
+} catch (Exception $e) {
+	$newpol = new KADM5Policy('some');
+	$conn->createPolicy($newpol);
+	$policy = $conn->getPolicy('some');
+}
+
+var_dump($policy->getPropertyArray());
+
+//$policy->setMinPasswordLife(1000);
+//$policy->setMaxPasswordLife(6*31*24*60*60);
+//$policy->setMinPasswordClasses(2);
+//$policy->setHistoryNum(5);
+//$policy->setMinPasswordLength(8);
+
+$policy->save();
+
+$princ = $conn->getPrincipal('testuser');
+var_dump($princ->getPolicy());
+$princ->clearPolicy();
+$princ->save();
+
+$policy->load();
+var_dump($policy->getPropertyArray());
+
+
+try {
+	$policy = $conn->getPolicy('testing');
+	$policy->delete();
+} catch (Exception $e) {
+}
+
+$newpol = new KADM5Policy('testing');
+$newpol->setMinPasswordLife(500023523);
+$newpol->setHistoryNum(10);
+echo $newpol->getName();
+$conn->createPolicy($newpol);
+
+var_dump($newpol->getPropertyArray());
+
+
+echo "\nAvailable policies\n";
+foreach($conn->getPolicies() as $policy) {
+	$usage = $conn->getPolicy($policy)->getReferenceCount();
+	echo " + $policy ($usage)\n";
+}
+
+
+$newpol->delete();
+
+
+?>

Copied: pecl/krb5/tags/krb5-1.1.0/trunk/examples/kadm/ex5.php (from rev 339675, \
pecl/krb5/trunk/examples/kadm/ex5.php) \
                ===================================================================
--- pecl/krb5/tags/krb5-1.1.0/trunk/examples/kadm/ex5.php	                        \
                (rev 0)
+++ pecl/krb5/tags/krb5-1.1.0/trunk/examples/kadm/ex5.php	2016-07-16 14:46:31 UTC \
(rev 339676) @@ -0,0 +1,7 @@
+<?php
+
+
+$princ = new KRB5CCache();
+$princ->initPassword('test1', 'foo123');
+var_dump($princ->getEntries());
+?>

Copied: pecl/krb5/tags/krb5-1.1.0/trunk/examples/kadm/ex6.php (from rev 339675, \
pecl/krb5/trunk/examples/kadm/ex6.php) \
                ===================================================================
--- pecl/krb5/tags/krb5-1.1.0/trunk/examples/kadm/ex6.php	                        \
                (rev 0)
+++ pecl/krb5/tags/krb5-1.1.0/trunk/examples/kadm/ex6.php	2016-07-16 14:46:31 UTC \
(rev 339676) @@ -0,0 +1,34 @@
+<?php
+$conn = new KADM5('test2/admin', 'test.keytab', true);
+
+
+try {
+	$policy = $conn->getPolicy('testing');
+	$policy->delete();
+} catch (Exception $e) {
+}
+
+$newpol = new KADM5Policy('testing');
+$newpol->setMinPasswordLength(10);
+$newpol->setMinPasswordClasses(3);
+$conn->createPolicy($newpol);
+
+
+try {
+	$princ = $conn->getPrincipal('testuser');
+	$princ->delete();
+} catch (Exception $e) {
+	echo $e;
+}
+
+$princ = new KADM5Principal('testuser');
+$conn->createPrincipal($princ , 'testpass');
+
+// either of this should work
+//$princ->setPolicy($conn->getPolicy('testing'));
+$princ->setPolicy($newpol);
+//$princ->setPolicy('testing');
+
+$princ->save();
+
+var_dump($princ);

Copied: pecl/krb5/tags/krb5-1.1.0/trunk/examples/kadm/ex7.php (from rev 339675, \
pecl/krb5/trunk/examples/kadm/ex7.php) \
                ===================================================================
--- pecl/krb5/tags/krb5-1.1.0/trunk/examples/kadm/ex7.php	                        \
                (rev 0)
+++ pecl/krb5/tags/krb5-1.1.0/trunk/examples/kadm/ex7.php	2016-07-16 14:46:31 UTC \
(rev 339676) @@ -0,0 +1,13 @@
+<?php
+
+$config = array(
+	'realm' => 'FOREIGN',
+	'admin_server' => 'kdc.foreign',
+	'kadmind_port' => 1234
+);
+
+// need to specify the realm in principal,
+// otherwise krb5.conf default realm is used
+$conn = new KADM5('testpw/admin@FOREIGN', 'asdfgh', false, $config);
+
+

Copied: pecl/krb5/tags/krb5-1.1.0/trunk/examples/kadm/ex8.php (from rev 339675, \
pecl/krb5/trunk/examples/kadm/ex8.php) \
                ===================================================================
--- pecl/krb5/tags/krb5-1.1.0/trunk/examples/kadm/ex8.php	                        \
                (rev 0)
+++ pecl/krb5/tags/krb5-1.1.0/trunk/examples/kadm/ex8.php	2016-07-16 14:46:31 UTC \
(rev 339676) @@ -0,0 +1,11 @@
+<?php
+
+$credopts = array(
+	'forwardable' => true,
+	'proxiable' => true
+);
+
+$ccache = new KRB5CCache();
+
+$ccache->initPassword("test", "foo", $credopts);
+

Copied: pecl/krb5/tags/krb5-1.1.0/trunk/examples/kadm/ex9.php (from rev 339675, \
pecl/krb5/trunk/examples/kadm/ex9.php) \
                ===================================================================
--- pecl/krb5/tags/krb5-1.1.0/trunk/examples/kadm/ex9.php	                        \
                (rev 0)
+++ pecl/krb5/tags/krb5-1.1.0/trunk/examples/kadm/ex9.php	2016-07-16 14:46:31 UTC \
(rev 339676) @@ -0,0 +1,29 @@
+<?php
+
+$config = array(
+	'realm' => 'SPRINGFIELD',
+	'admin_server' => 'homer.springfield'
+);
+
+// need to specify the realm in principal,
+// otherwise krb5.conf default realm is used
+$conn = new KADM5('testpw/admin@SPRINGFIELD', 'asdfgh', false, $config);
+
+$princ = $conn->getPrincipal("testuser@SPRINGFIELD");
+var_dump($princ->getAttributes());
+var_dump($princ->getAuxAttributes());
+var_dump($princ->getPropertyArray());
+var_dump($princ->getTLData());
+echo "Before\n";
+$princ->setTLData(array(new KADM5TLData(KRB5_TL_DB_ARGS, "tktpolicy=\0")));
+foreach ( $princ->getTLData() as $tldata) {
+	echo $tldata->getType() . ":" . $tldata->getData() . "\n";
+}
+$princ->save();
+
+echo "After\n";
+var_dump($princ->getPropertyArray());
+
+foreach ( $princ->getTLData() as $tldata) {
+	echo $tldata->getType() . ":" . $tldata->getData() . "\n";
+}

Copied: pecl/krb5/tags/krb5-1.1.0/trunk/examples/spnego.php (from rev 339675, \
pecl/krb5/trunk/examples/spnego.php) \
                ===================================================================
--- pecl/krb5/tags/krb5-1.1.0/trunk/examples/spnego.php	                        (rev \
                0)
+++ pecl/krb5/tags/krb5-1.1.0/trunk/examples/spnego.php	2016-07-16 14:46:31 UTC (rev \
339676) @@ -0,0 +1,28 @@
+<?php
+if(!extension_loaded('krb5')) {
+	die('KRB5 Extension not installed');
+}
+
+$auth = new KRB5NegotiateAuth('/etc/krb5.keytab');
+
+
+if($auth->doAuthentication()) {
+	echo 'Success - authenticated as ' . $auth->getAuthenticatedUser();
+
+	try {
+		$cc = new KRB5CCache();
+		$auth->getDelegatedCredentials($cc);
+	} catch (Exception $error) {
+		echo 'No delegated credentials available';
+	}
+} else {
+	if(!empty($_SERVER['PHP_AUTH_USER'])) {
+		header('HTTP/1.1 401 Unauthorized');
+		header('WWW-Authenticate: Basic', false);
+	} else {
+		// verify basic authentication data
+		echo 'authenticated using BASIC method<br />';
+	}
+}
+
+?>

Copied: pecl/krb5/tags/krb5-1.1.0/trunk/gssapi.c (from rev 339675, \
pecl/krb5/trunk/gssapi.c) \
                ===================================================================
--- pecl/krb5/tags/krb5-1.1.0/trunk/gssapi.c	                        (rev 0)
+++ pecl/krb5/tags/krb5-1.1.0/trunk/gssapi.c	2016-07-16 14:46:31 UTC (rev 339676)
@@ -0,0 +1,988 @@
+/**
+* Copyright (c) 2008 Moritz Bechler
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+* THE SOFTWARE.
+**/
+
+
+#include "php.h"
+#include "php_krb5.h"
+#include "compat.h"
+
+/* Class definition */
+
+zend_class_entry *krb5_ce_gssapi_context;
+
+typedef struct _krb5_gssapi_context_object {
+#if PHP_MAJOR_VERSION < 7
+		zend_object std;
+#endif
+		gss_cred_id_t creds;
+		gss_ctx_id_t context;
+#if PHP_MAJOR_VERSION >= 7
+		zend_object std;
+#endif
+} krb5_gssapi_context_object;
+
+ZEND_BEGIN_ARG_INFO_EX(krb5_GSSAPIContext_registerAcceptorIdentity, 0, 0, 1)
+	ZEND_ARG_INFO(0, keytab)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(krb5_GSSAPIContext_acquireCredentials, 0, 0, 1)
+	ZEND_ARG_OBJ_INFO(0, ccache, KRB5CCache, 0)
+	ZEND_ARG_INFO(0, name)
+	ZEND_ARG_INFO(0, type)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(krb5_GSSAPIContext_none, 0, 0, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(krb5_GSSAPIContext_initSecContextArgs, 0, 0, 1)
+	ZEND_ARG_INFO(0, target)
+	ZEND_ARG_INFO(0, input_token)
+	ZEND_ARG_INFO(0, reqflags)
+	ZEND_ARG_INFO(0, timereq)
+	ZEND_ARG_INFO(1, output_token)
+	ZEND_ARG_INFO(1, ret_flags)
+	ZEND_ARG_INFO(1, time_rec)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(krb5_GSSAPIContext_acceptSecContextArgs, 0, 0, 1)
+	ZEND_ARG_INFO(0, input_token)
+	ZEND_ARG_INFO(1, output_token)
+	ZEND_ARG_INFO(1, src_name)
+	ZEND_ARG_INFO(1, ret_flags)
+	ZEND_ARG_INFO(1, time_rec)
+	ZEND_ARG_OBJ_INFO(0, deleg, KRB5CCache, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(krb5_GSSAPIContext_getMic, 0, 0, 1)
+	ZEND_ARG_INFO(0, message)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(krb5_GSSAPIContext_verifyMicArgs, 0, 0, 2)
+	ZEND_ARG_INFO(0, message)
+	ZEND_ARG_INFO(0, mic)
+ZEND_END_ARG_INFO()
+
+
+ZEND_BEGIN_ARG_INFO_EX(krb5_GSSAPIContext_wrapArgs, 0, 0, 2)
+	ZEND_ARG_INFO(0, input)
+	ZEND_ARG_INFO(1, output)
+	ZEND_ARG_INFO(0, encrypt)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(krb5_GSSAPIContext_unwrapArgs, 0, 0, 2)
+	ZEND_ARG_INFO(0, input)
+	ZEND_ARG_INFO(1, output)
+ZEND_END_ARG_INFO()
+
+
+PHP_METHOD(GSSAPIContext, registerAcceptorIdentity);
+PHP_METHOD(GSSAPIContext, acquireCredentials);
+PHP_METHOD(GSSAPIContext, inquireCredentials);
+PHP_METHOD(GSSAPIContext, initSecContext);
+PHP_METHOD(GSSAPIContext, acceptSecContext);
+PHP_METHOD(GSSAPIContext, getMic);
+PHP_METHOD(GSSAPIContext, verifyMic);
+PHP_METHOD(GSSAPIContext, wrap);
+PHP_METHOD(GSSAPIContext, unwrap);
+PHP_METHOD(GSSAPIContext, getTimeRemaining);
+
+static zend_function_entry krb5_gssapi_context_functions[] = {
+	PHP_ME(GSSAPIContext, registerAcceptorIdentity, \
krb5_GSSAPIContext_registerAcceptorIdentity, ZEND_ACC_PUBLIC) +	PHP_ME(GSSAPIContext, \
acquireCredentials,       krb5_GSSAPIContext_acquireCredentials,       \
ZEND_ACC_PUBLIC) +	PHP_ME(GSSAPIContext, inquireCredentials,       \
krb5_GSSAPIContext_none,                     ZEND_ACC_PUBLIC) +	PHP_ME(GSSAPIContext, \
initSecContext,           krb5_GSSAPIContext_initSecContextArgs,       \
ZEND_ACC_PUBLIC) +	PHP_ME(GSSAPIContext, acceptSecContext,         \
krb5_GSSAPIContext_acceptSecContextArgs,     ZEND_ACC_PUBLIC) +	PHP_ME(GSSAPIContext, \
getMic,                   krb5_GSSAPIContext_getMic,                   \
ZEND_ACC_PUBLIC) +	PHP_ME(GSSAPIContext, verifyMic,                \
krb5_GSSAPIContext_verifyMicArgs,            ZEND_ACC_PUBLIC) +	PHP_ME(GSSAPIContext, \
wrap,                     krb5_GSSAPIContext_wrapArgs,                 \
ZEND_ACC_PUBLIC) +	PHP_ME(GSSAPIContext, unwrap,                   \
krb5_GSSAPIContext_unwrapArgs,               ZEND_ACC_PUBLIC) +	PHP_ME(GSSAPIContext, \
getTimeRemaining,         krb5_GSSAPIContext_none,                     \
ZEND_ACC_PUBLIC) +	PHP_FE_END
+};
+
+zend_object_handlers krb5_gssapi_context_handlers;
+
+#ifdef ZTS
+MUTEX_T gssapi_mutex;
+#endif
+
+/* Helper functions */
+
+#define ASSERT_GSS_SUCCESS(status,minor_status,retval) if(GSS_ERROR(status)) { \
+	php_krb5_gssapi_handle_error(status, minor_status TSRMLS_CC); \
+	RETURN_FALSE; \
+}
+
+/* {{{ */
+void php_krb5_gssapi_handle_error(OM_uint32 major, OM_uint32 minor TSRMLS_DC)
+{
+	OM_uint32 error_context = 0;
+	OM_uint32 minor_status = 0;
+	gss_buffer_desc error_buffer;
+
+	gss_display_status (&minor_status, major, GSS_C_GSS_CODE,
+					GSS_C_NO_OID, &error_context, &error_buffer);
+
+
+	while(error_context) {
+		php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s (%ld,%ld)", (char*) \
error_buffer.value, (unsigned long int) major, (unsigned long int)minor); \
+		gss_release_buffer(&minor_status, &error_buffer); +		gss_display_status \
(&minor_status, major, GSS_C_GSS_CODE, +				GSS_C_NO_OID, &error_context, \
&error_buffer); +	}
+	php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s (%ld,%ld)", (char*) \
error_buffer.value,  (unsigned long int) major,  (unsigned long int)minor); \
+	gss_release_buffer(&minor_status, &error_buffer); +
+	if(minor) {
+		php_error_docref(NULL TSRMLS_CC, E_WARNING, "GSSAPI mechanism error #%ld",  \
(unsigned long int) minor); +		gss_display_status (&minor_status, minor, \
GSS_C_MECH_CODE, +					GSS_C_NO_OID, &error_context, &error_buffer);
+
+		while(error_context) {
+			php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", (char*) error_buffer.value);
+			gss_release_buffer(&minor_status, &error_buffer);
+
+			gss_display_status (&minor_status, minor_status, GSS_C_MECH_CODE,
+                                                GSS_C_NO_OID, &error_context, \
&error_buffer); +		}
+		php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s (%ld)", (char*)  \
error_buffer.value,  (unsigned long int) minor); +		gss_release_buffer(&minor_status, \
&error_buffer); +	}
+}
+/* }}} */
+
+/* Setup functions */
+
+/* {{{ */
+#if PHP_MAJOR_VERSION < 7
+void php_krb5_gssapi_context_object_dtor(void *obj, zend_object_handle handle \
TSRMLS_DC) +{
+	OM_uint32 minor_status = 0;
+	krb5_gssapi_context_object *object = (krb5_gssapi_context_object*)obj;
+	OBJECT_STD_DTOR(object->std);
+
+
+	if(object->creds != GSS_C_NO_CREDENTIAL) {
+		gss_release_cred(&minor_status, &object->creds);
+	}
+
+	if(object->context != GSS_C_NO_CONTEXT) {
+		gss_delete_sec_context(&minor_status, &object->context,  GSS_C_NO_BUFFER);
+	}
+
+	efree(object);
+}
+#else
+void php_krb5_gssapi_context_object_free(zend_object *obj TSRMLS_DC) {
+	OM_uint32 minor_status = 0;
+	krb5_gssapi_context_object *object = (krb5_gssapi_context_object*)((char *)obj - \
XtOffsetOf(krb5_gssapi_context_object, std)); +
+	if(object->creds != GSS_C_NO_CREDENTIAL) {
+		gss_release_cred(&minor_status, &object->creds);
+	}
+
+	if(object->context != GSS_C_NO_CONTEXT) {
+		gss_delete_sec_context(&minor_status, &object->context,  GSS_C_NO_BUFFER);
+	}
+	zend_object_std_dtor(obj);
+}
+#endif
+/* }}} */
+
+
+/* {{{ */
+#if PHP_MAJOR_VERSION < 7
+zend_object_value php_krb5_gssapi_context_object_new(zend_class_entry *ce TSRMLS_DC)
+{
+	zend_object_value retval;
+	krb5_gssapi_context_object *object;
+
+	object = emalloc(sizeof(krb5_gssapi_context_object));
+
+	object->context = GSS_C_NO_CONTEXT;
+	object->creds = GSS_C_NO_CREDENTIAL;
+
+	INIT_STD_OBJECT(object->std, ce);
+
+#if PHP_VERSION_ID < 50399
+	zend_hash_copy(object->std.properties, &ce->default_properties,
+	        		(copy_ctor_func_t) zval_add_ref, NULL,
+					sizeof(zval*));
+#else
+	object_properties_init(&(object->std), ce);
+#endif
+
+	retval.handle = zend_objects_store_put(object, php_krb5_gssapi_context_object_dtor, \
NULL, NULL TSRMLS_CC); +
+	retval.handlers = &krb5_gssapi_context_handlers;
+	return retval;
+}
+#else
+zend_object *php_krb5_gssapi_context_object_new(zend_class_entry *ce TSRMLS_DC) {
+	krb5_gssapi_context_object *object;
+	object = ecalloc(1, sizeof(krb5_gssapi_context_object) + \
zend_object_properties_size(ce)); +
+	object->context = GSS_C_NO_CONTEXT;
+	object->creds = GSS_C_NO_CREDENTIAL;
+
+	zend_object_std_init(&object->std, ce TSRMLS_CC);
+	object_properties_init(&object->std, ce);
+	object->std.handlers = &krb5_gssapi_context_handlers;
+	return &object->std;
+}
+#endif
+/* }}} */
+
+/* {{{ */
+int php_krb5_gssapi_register_classes(TSRMLS_D)
+{
+	zend_class_entry gssapi_context;
+
+
+#ifdef ZTS
+	/* initialize GSSAPI mutex */
+	gssapi_mutex = tsrm_mutex_alloc();
+	if(!gssapi_mutex) {
+		php_error_docref(NULL TSRMLS_CC, E_ERROR, "Failed to initialize mutex in GSSAPI \
module"); +		return FAILURE;
+	}
+#endif
+
+
+	/* register classes */
+	INIT_CLASS_ENTRY(gssapi_context, "GSSAPIContext", krb5_gssapi_context_functions);
+	krb5_ce_gssapi_context = zend_register_internal_class(&gssapi_context TSRMLS_CC);
+	krb5_ce_gssapi_context->create_object = php_krb5_gssapi_context_object_new;
+
+	memcpy(&krb5_gssapi_context_handlers, zend_get_std_object_handlers(), \
sizeof(zend_object_handlers)); +#if PHP_MAJOR_VERSION >= 7
+	krb5_gssapi_context_handlers.offset = XtOffsetOf(krb5_gssapi_context_object, std);
+	krb5_gssapi_context_handlers.free_obj = php_krb5_gssapi_context_object_free;
+#endif
+
+	return SUCCESS;
+}
+/* }}} */
+
+/* {{{ */
+int php_krb5_gssapi_shutdown(TSRMLS_D)
+{
+#ifdef ZTS
+	tsrm_mutex_free(gssapi_mutex);
+#endif
+
+	return SUCCESS;
+}
+/* }}} */
+
+
+/* GSSAPI Methods */
+
+/* {{{ proto void GSSAPIContext::registerAcceptorIdentity(string $keytab)
+ */
+PHP_METHOD(GSSAPIContext, registerAcceptorIdentity)
+{
+	char *keytab;
+	strsize_t keytab_len = 0;
+
+	if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, ARG_PATH, &keytab, &keytab_len) \
== FAILURE) { +		RETURN_FALSE;
+	}
+
+	if(krb5_gss_register_acceptor_identity(keytab) != GSS_S_COMPLETE) {
+		zend_throw_exception(NULL, "Failed to set acceptor identitiy", 0 TSRMLS_CC);
+		return;
+	}
+}
+
+
+#ifdef ZTS
+#define LOCK_MUTEX \
+	if(tsrm_mutex_lock(gssapi_mutex)) { \
+		php_error_docref(NULL TSRMLS_CC,  E_ERROR, "Failed to obtain mutex lock in GSSAPI \
module");\ +		return;\
+	}
+#define UNLOCK_MUTEX \
+	if(tsrm_mutex_unlock(gssapi_mutex)) {\
+		php_error_docref(NULL TSRMLS_CC,  E_ERROR, "Failed to release mutex lock in GSSAPI \
module");\ +		return;\
+	}
+#else
+#define LOCK_MUTEX
+#define UNLOCK_MUTEX
+#endif
+
+#define STORE_CONTEXT(ccache, oldkrb5ccname, oldkrb5ktname) { \
+	const char *ccnametmp = krb5_cc_get_name(ccache->ctx, ccache->cc); \
+        const char *cctypetmp = krb5_cc_get_type(ccache->ctx, ccache->cc); \
+\
+	ccname = malloc(strlen(ccnametmp) + strlen(cctypetmp) + 2); \
+	memset(ccname,0, strlen(ccnametmp) + strlen(cctypetmp) + 2); \
+\
+	strcat(ccname, cctypetmp);\
+	strcat(ccname, ":");\
+	strcat(ccname, ccnametmp);\
+	LOCK_MUTEX\
+	/* save current KRB5CCNAME for resetting purposes */\
+	oldkrb5ccname = getenv("KRB5CCNAME");\
+	oldkrb5ktname = getenv("KRB5_KTNAME");\
+\
+	setenv("KRB5CCNAME", ccname, 1);\
+	if(ccache->keytab) {\
+		setenv("KRB5_KTNAME", ccache->keytab, 1);\
+	}\
+	free(ccname);\
+}
+
+#define RESTORE_CONTEXT(oldkrb5ccname, oldkrb5ktname) \
+	/* reset KRB5CCNAME environment */\
+	if(oldkrb5ccname) {\
+		setenv("KRB5CCNAME", oldkrb5ccname, 1);\
+	} else {\
+		unsetenv("KRB5CCNAME");\
+	}\
+\
+	if(oldkrb5ktname) {\
+		setenv("KRB5_KTNAME", oldkrb5ktname, 1);\
+	} else {\
+		unsetenv("KRB5_KTNAME");\
+	}\
+	UNLOCK_MUTEX
+
+
+/* {{{ proto void GSSAPIContext::acquireCredentials( KRB5CCache $ccache [, string \
$name = null [, int $type = GSS_C_BOTH ]]) +   Obtain credentials for context \
establishment  */ +PHP_METHOD(GSSAPIContext, acquireCredentials)
+{
+	OM_uint32           status = 0;
+	OM_uint32           minor_status = 0;
+
+	zval* zccache;
+	krb5_ccache_object *ccache = NULL;
+	char *ccname = NULL;
+
+	zend_long type = GSS_C_BOTH;
+
+	char *pname = NULL;
+	gss_buffer_desc nametmp;
+	gss_name_t name = GSS_C_NO_NAME;
+	strsize_t namelen = 0;
+
+	memset(&nametmp, 0, sizeof(nametmp));
+
+
+	krb5_gssapi_context_object *context = KRB5_THIS_GSSAPI_CONTEXT;
+
+	if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|sl", &zccache, \
krb5_ce_ccache, +		&(nametmp.value), &namelen,
+		&type) == FAILURE) {
+		RETURN_FALSE;
+	}
+	if ( namelen > 0 ) {
+		nametmp.length = namelen;
+	}
+
+	ccache = KRB5_CCACHE(zccache);
+
+	if ( ccache->keytab == NULL ) {
+		type = GSS_C_INITIATE;
+	}
+
+	char *oldkrb5ccname = NULL, *oldkrb5ktname = NULL;
+	STORE_CONTEXT(ccache, oldkrb5ccname, oldkrb5ktname);
+
+	if(context->creds != GSS_C_NO_CREDENTIAL) {
+		gss_release_cred(&minor_status, &(context->creds));
+	}
+
+
+	if(nametmp.length == 0) {
+		krb5_principal ccprinc;
+		krb5_error_code err = krb5_cc_get_principal(ccache->ctx, ccache->cc, &ccprinc);
+		if ( err != 0 ) {
+			RESTORE_CONTEXT(oldkrb5ccname, oldkrb5ktname);
+			zend_throw_exception(NULL, "Failed to locate default principal in ccache", 0 \
TSRMLS_CC); +			return;
+		}
+
+		krb5_unparse_name(ccache->ctx, ccprinc, &pname);
+		nametmp.value = pname;
+		nametmp.length = strlen(pname);
+		krb5_free_principal(ccache->ctx, ccprinc);
+	}
+
+
+	if(nametmp.length != 0) {
+		status = gss_import_name(&minor_status, &nametmp, GSS_C_NO_OID, &name);
+
+		if(GSS_ERROR(status)) {
+			if ( pname != NULL ) {
+				krb5_free_unparsed_name(ccache->ctx, pname);
+			}
+			RESTORE_CONTEXT(oldkrb5ccname, oldkrb5ktname);
+			ASSERT_GSS_SUCCESS(status,minor_status,);
+		}
+	}
+
+
+	if ( pname != NULL ) {
+		krb5_free_unparsed_name(ccache->ctx, pname);
+	}
+
+	status =  gss_acquire_cred (
+	     &minor_status,
+	     name,
+	     GSS_C_INDEFINITE,
+	     GSS_C_NO_OID_SET,
+	     type,
+	     &(context->creds),
+	     NULL,
+	     NULL);
+
+	RESTORE_CONTEXT(oldkrb5ccname, oldkrb5ktname);
+	ASSERT_GSS_SUCCESS(status,minor_status,);
+} /* }}} */
+
+/* {{{ proto array GSSAPIContext::inquireCredentials( )
+   Get information about the credentials used for context establishment  */
+PHP_METHOD(GSSAPIContext, inquireCredentials)
+{
+	OM_uint32           status = 0;
+	OM_uint32           minor_status = 0;
+	krb5_gssapi_context_object *context = KRB5_THIS_GSSAPI_CONTEXT;
+
+	gss_name_t name = GSS_C_NO_NAME;
+	OM_uint32 lifetime = 0;
+	gss_cred_usage_t cred_usage = GSS_C_BOTH;
+	gss_OID_set mechs = GSS_C_NO_OID_SET;
+	gss_buffer_desc nametmp;
+	memset(&nametmp, 0, sizeof(gss_buffer_desc));
+
+	if (zend_parse_parameters_none() == FAILURE) {
+		RETURN_FALSE;
+	}
+
+	status = gss_inquire_cred (
+	     &minor_status,
+	     context->creds,
+	     &name,
+	     &lifetime,
+	     &cred_usage,
+	     &mechs);
+
+	ASSERT_GSS_SUCCESS(status,minor_status,);
+
+
+	status = gss_display_name(&minor_status, name, &nametmp, NULL);
+	ASSERT_GSS_SUCCESS(status,minor_status,);
+
+	array_init(return_value);
+	char *nameval = estrdup(nametmp.value);
+	_add_assoc_string(return_value, "name", nameval);
+	efree(nameval);
+
+	add_assoc_long(return_value, "lifetime_remain", lifetime);
+
+	if(cred_usage == GSS_C_BOTH) {
+		_add_assoc_string(return_value, "cred_usage", "both");
+	} else if(cred_usage == GSS_C_INITIATE) {
+		_add_assoc_string(return_value, "cred_usage", "initiate");
+	} else if(cred_usage == GSS_C_ACCEPT) {
+		_add_assoc_string(return_value, "cred_usage", "accept");
+	}
+
+	status = gss_release_buffer(&minor_status, &nametmp);
+	ASSERT_GSS_SUCCESS(status,minor_status,);
+
+	status = gss_release_name(&minor_status, &name);
+	ASSERT_GSS_SUCCESS(status,minor_status,);
+
+	size_t i = 0;
+	_DECLARE_ZVAL(mech_array);
+	_ALLOC_INIT_ZVAL(mech_array);
+	array_init(mech_array);
+
+	for(i = 0; i < mechs->count; i++) {
+		gss_OID_desc oid = *(mechs->elements + i);
+		gss_buffer_desc tmp;
+		status = gss_oid_to_str(&minor_status, &oid, &tmp);
+		ASSERT_GSS_SUCCESS(status,minor_status,);
+
+		_add_next_index_string(mech_array, tmp.value);
+
+		status = gss_release_buffer(&minor_status, &tmp);
+		ASSERT_GSS_SUCCESS(status,minor_status,);
+	}
+
+	add_assoc_zval(return_value, "mechs", mech_array);
+
+	status = gss_release_oid_set(&minor_status, &mechs);
+	ASSERT_GSS_SUCCESS(status,minor_status,);
+
+} /* }}} */
+
+/* {{{ proto boolean GSSAPIContext::initSecContext( string $target [, string \
$input_token [, int $req_flags [, int $time_eq [, string &$output_token [, int \
&$ret_flags [, int &$time-rec ]]]]]] ) +   Initiate a security context */
+PHP_METHOD(GSSAPIContext, initSecContext)
+{
+	OM_uint32  status = 0;
+	OM_uint32  minor_status = 0;
+	krb5_gssapi_context_object *context = KRB5_THIS_GSSAPI_CONTEXT;
+
+
+	zend_long req_flags = 0;
+	OM_uint32 ret_flags = 0;
+	zend_long time_req = 0;
+	OM_uint32 time_rec = 0;
+	gss_buffer_desc tokenbuf;
+	gss_buffer_desc inputtoken;
+	gss_buffer_desc target;
+	strsize_t target_len = 0;
+	strsize_t inputtoken_len = 0;
+
+	memset(&inputtoken, 0, sizeof(inputtoken));
+	memset(&target, 0, sizeof(target));
+	memset(&tokenbuf, 0, sizeof(tokenbuf));
+
+	zval *ztokenbuf = NULL;
+	zval *zret_flags = NULL;
+	zval *ztime_rec = NULL;
+
+#if PHP_MAJOR_VERSION >= 7
+	const char *args = "s|sllz/z/z/";
+#else
+
+	const char *args = "s|sllzzz";
+#endif
+
+	if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, args,
+								&(target.value), &target_len,
+								&(inputtoken.value), &inputtoken_len,
+								&req_flags,
+								&time_req,
+								&ztokenbuf,
+								&zret_flags,
+								&ztime_rec
+								) == FAILURE) {
+		return;
+	}
+	target.length = target_len;
+	inputtoken.length = inputtoken_len;
+
+
+
+	gss_name_t targetname;
+	status = gss_import_name(&minor_status, &target,GSS_C_NO_OID, &targetname);
+	ASSERT_GSS_SUCCESS(status,minor_status,);
+
+	status =  gss_init_sec_context(
+	     &minor_status,
+	     context->creds,
+	     &context->context,
+	     targetname,
+	     GSS_C_NO_OID,
+	     req_flags,
+	     time_req,
+	     NULL,
+	     &inputtoken,
+	     NULL,
+	     &tokenbuf,
+	     &ret_flags,
+	     &time_rec);
+
+	if(status & GSS_S_CONTINUE_NEEDED) {
+		RETVAL_FALSE;
+	} else if(status) {
+		gss_release_name(&minor_status, &targetname);
+		gss_release_buffer(&minor_status, &tokenbuf);
+		ASSERT_GSS_SUCCESS(status,minor_status,);
+	} else {
+		RETVAL_TRUE;
+	}
+
+	if(ztokenbuf) {
+		zval_dtor(ztokenbuf);
+		_ZVAL_STRINGL(ztokenbuf, tokenbuf.value, tokenbuf.length);
+	}
+
+	status = gss_release_buffer(&minor_status, &tokenbuf);
+	ASSERT_GSS_SUCCESS(status,minor_status,);
+
+	if(zret_flags) {
+		zval_dtor(zret_flags);
+		ZVAL_LONG(zret_flags, ret_flags);
+	}
+
+	if(ztime_rec) {
+		zval_dtor(ztime_rec);
+		ZVAL_LONG(ztime_rec, time_rec);
+	}
+
+	status = gss_release_name(&minor_status, &targetname);
+	ASSERT_GSS_SUCCESS(status,minor_status,);
+
+
+} /* }}} */
+
+/* {{{ proto boolean GSSAPIContext::acceptSecContext( string $token [, string \
&$output_token [, string &$remote_principal [, int &$ret_flags [, int &$time_rec [, \
KRB5CCache deleg]]]]] ) +   Establish/accept a remotely initiated security context */
+PHP_METHOD(GSSAPIContext, acceptSecContext)
+{
+	OM_uint32           status = 0;
+	OM_uint32           minor_status = 0;
+	krb5_gssapi_context_object *context = KRB5_THIS_GSSAPI_CONTEXT;
+
+	gss_buffer_desc inputtoken;
+	gss_buffer_desc tokenbuf;
+	gss_name_t src_name = GSS_C_NO_NAME;
+	gss_cred_id_t deleg_creds = GSS_C_NO_CREDENTIAL;
+	strsize_t inputtoken_len = 0;
+
+	memset(&inputtoken, 0, sizeof(inputtoken));
+	memset(&tokenbuf, 0, sizeof(tokenbuf));
+
+	OM_uint32 ret_flags = 0;
+	OM_uint32 time_rec = 0;
+
+	zval* ztokenbuf = NULL;
+	zval* zret_flags = NULL;
+	zval* ztime_rec = NULL;
+	zval* zsrc_name = NULL;
+	zval* zdeleg_creds = NULL;
+
+#if PHP_MAJOR_VERSION >= 7
+	const char *args = "s|z/z/z/z/O";
+#else
+
+	const char *args = "s|zzzzO";
+#endif
+
+	if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, args,
+			&(inputtoken.value), &inputtoken_len,
+			&ztokenbuf,
+			&zsrc_name,
+			&zret_flags,
+			&ztime_rec,
+			&zdeleg_creds, krb5_ce_ccache) == FAILURE) {
+		return;
+	}
+
+	inputtoken.length = inputtoken_len;
+
+	status =  gss_accept_sec_context (
+			&minor_status,
+			&context->context,
+			context->creds,
+			&inputtoken,
+			GSS_C_NO_CHANNEL_BINDINGS,
+			&src_name,
+			NULL,
+			&tokenbuf,
+			&ret_flags,
+			&time_rec,
+			&deleg_creds);
+
+	 if(status & GSS_S_CONTINUE_NEEDED) {
+		 RETVAL_FALSE;
+	 } else if(GSS_ERROR(status)) {
+		 OM_uint32 tmpstat = 0;
+		 gss_release_name(&tmpstat, &src_name);
+		 gss_release_buffer(&tmpstat, &tokenbuf);
+		 RETVAL_FALSE;
+		 ASSERT_GSS_SUCCESS(status,minor_status,);
+	 } else {
+		 RETVAL_TRUE;
+	 }
+
+	 if(ztokenbuf) {
+		 zval_dtor(ztokenbuf);
+		 _ZVAL_STRINGL(ztokenbuf, tokenbuf.value, tokenbuf.length);
+	 }
+
+	 status = gss_release_buffer(&minor_status, &tokenbuf);
+	 ASSERT_GSS_SUCCESS(status,minor_status,);
+
+	 if(zsrc_name) {
+		 gss_buffer_desc nametmp;
+		 status = gss_display_name(&minor_status, src_name, &nametmp, NULL);
+		 ASSERT_GSS_SUCCESS(status,minor_status,);
+		 zval_dtor(zsrc_name);
+		 _ZVAL_STRINGL(zsrc_name, nametmp.value, nametmp.length);
+		 status = gss_release_buffer(&minor_status, &nametmp);
+		 ASSERT_GSS_SUCCESS(status,minor_status,);
+	 }
+
+	 if(zret_flags) {
+		 zval_dtor(zret_flags);
+		 ZVAL_LONG(zret_flags, ret_flags);
+	 }
+
+	 if(ztime_rec) {
+		 zval_dtor(ztime_rec);
+		 ZVAL_LONG(ztime_rec, time_rec);
+	 }
+
+	 if(zdeleg_creds && deleg_creds != GSS_C_NO_CREDENTIAL) {
+		 krb5_ccache_object *deleg_ccache = KRB5_CCACHE(zdeleg_creds);
+		 krb5_error_code retval = 0;
+		 krb5_principal princ;
+
+		 if(!deleg_ccache) {
+			 zend_throw_exception(NULL, "Invalid KRB5CCache object given", 0 TSRMLS_CC);
+			 RETURN_FALSE;
+		 }
+
+		 /* use principal name for ccache initialization */
+		 gss_buffer_desc nametmp;
+		 status = gss_display_name(&minor_status, src_name, &nametmp, NULL);
+		 ASSERT_GSS_SUCCESS(status,minor_status,);
+
+		 if((retval = krb5_parse_name(deleg_ccache->ctx, nametmp.value, &princ))) {
+			 php_krb5_display_error(deleg_ccache->ctx, retval,  "Failed to parse principal \
name (%s)" TSRMLS_CC); +			 RETURN_FALSE;
+		 }
+
+		 if((retval = krb5_cc_initialize(deleg_ccache->ctx, deleg_ccache->cc, princ))) {
+		 		krb5_free_principal(deleg_ccache->ctx,princ);
+		 		php_krb5_display_error(deleg_ccache->ctx, retval,  "Failed to initialize \
credential cache (%s)" TSRMLS_CC); +		 		RETURN_FALSE;
+		 }
+
+		 krb5_free_principal(deleg_ccache->ctx,princ);
+		 /* copy credentials to ccache */
+		 status = gss_krb5_copy_ccache(&minor_status, deleg_creds, deleg_ccache->cc);
+
+		 if(GSS_ERROR(status)) {
+			 php_krb5_gssapi_handle_error(status, minor_status TSRMLS_CC);
+			 zend_throw_exception(NULL, "Failure while imporing delegated ticket", 0 \
TSRMLS_CC); +			 RETURN_FALSE;
+		 }
+	 }
+
+	 status = gss_release_name(&minor_status, &src_name);
+	 ASSERT_GSS_SUCCESS(status,minor_status,);
+
+} /* }}} */
+
+/* {{{ proto int GSSAPIContext::getTimeRemaining( )
+   Returns the time in seconds the GSSAPI context will stay valid  */
+PHP_METHOD(GSSAPIContext, getTimeRemaining)
+{
+	OM_uint32 status = 0;
+	OM_uint32 minor_status = 0;
+	OM_uint32 time_rec = 0;
+	krb5_gssapi_context_object *context = KRB5_THIS_GSSAPI_CONTEXT;
+
+	if (zend_parse_parameters_none() == FAILURE) {
+		RETURN_FALSE;
+	}
+	if(context->context == GSS_C_NO_CONTEXT) {
+		RETURN_LONG(0);
+	}
+
+	status = gss_context_time(&minor_status, context->context, &time_rec);
+
+	ASSERT_GSS_SUCCESS(status,minor_status,);
+
+	RETURN_LONG(time_rec);
+} /* }}} */
+
+/* {{{ proto string GSSAPIContext::getMic( string message )
+   Calculates a MIC for the given message */
+PHP_METHOD(GSSAPIContext, getMic)
+{
+	OM_uint32 status = 0;
+	OM_uint32 minor_status = 0;
+	gss_buffer_desc input;
+	gss_buffer_desc output;
+	krb5_gssapi_context_object *context = KRB5_THIS_GSSAPI_CONTEXT;
+	strsize_t input_length = 0;
+
+	memset(&input, 0 , sizeof(input));
+
+
+	if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s",
+			&(input.value), &input_length) == FAILURE) {
+		return;
+	}
+	input.length = input_length;
+
+
+	status = gss_get_mic (
+	     &minor_status,
+	     context->context,
+	     GSS_C_QOP_DEFAULT,
+	     &input,
+	     &output);
+
+
+	ASSERT_GSS_SUCCESS(status,minor_status,);
+
+	_RETVAL_STRINGL(output.value, output.length);
+
+	status = gss_release_buffer(&minor_status, &output);
+	ASSERT_GSS_SUCCESS(status,minor_status,);
+} /* }}} */
+
+/* {{{ proto bool GSSAPIContext::verifyMic( string $input, string $mic)
+   Verifies a given message against a MIC */
+PHP_METHOD(GSSAPIContext, verifyMic)
+{
+	OM_uint32 status = 0;
+	OM_uint32 minor_status = 0;
+	gss_buffer_desc input;
+	gss_buffer_desc mic;
+	krb5_gssapi_context_object *context = KRB5_THIS_GSSAPI_CONTEXT;
+	strsize_t input_length = 0;
+	strsize_t mic_length = 0;
+
+	memset(&input, 0 , sizeof(input));
+	memset(&mic, 0 , sizeof(mic));
+
+
+	if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss",
+			&(input.value), &input_length,
+			&(mic.value), &mic_length) == FAILURE) {
+		return;
+	}
+	input.length = input_length;
+	mic.length = mic_length;
+
+	status =  gss_verify_mic (
+			&minor_status,
+			context->context,
+			&input,
+			&mic,
+			NULL);
+
+	RETVAL_FALSE;
+
+	ASSERT_GSS_SUCCESS(status,minor_status,);
+
+	RETVAL_TRUE;
+} /* }}} */
+
+/* {{{ proto bool GSSAPIContext::wrap( string $input, string &$output [, bool \
$encrypt = false ]) +   Attaches a MIC to an input message and possibly encrypts the \
message */ +PHP_METHOD(GSSAPIContext, wrap)
+{
+	OM_uint32 status = 0;
+	OM_uint32 minor_status = 0;
+	gss_buffer_desc input;
+	gss_buffer_desc output;
+	zval *zoutput;
+	zend_long encrypt = 0;
+	krb5_gssapi_context_object *context = KRB5_THIS_GSSAPI_CONTEXT;
+	strsize_t input_length = 0;
+
+	memset(&input, 0 , sizeof(input));
+	memset(&output, 0 , sizeof(output));
+
+#if PHP_MAJOR_VERSION >= 7
+	const char *args = "sz/|b";
+#else
+	const char *args = "sz|b";
+#endif
+
+	if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, args,
+			&(input.value), &input_length,
+			&zoutput,
+			&encrypt) == FAILURE) {
+		return;
+	}
+	input.length = input_length;
+
+	RETVAL_FALSE;
+
+	status = gss_wrap (
+			&minor_status,
+			context->context,
+			encrypt,
+			GSS_C_QOP_DEFAULT,
+			&input,
+			NULL,
+			&output);
+
+	ASSERT_GSS_SUCCESS(status,minor_status,);
+
+	if(zoutput) {
+		zval_dtor(zoutput);
+		_ZVAL_STRINGL(zoutput, output.value, output.length);
+	}
+
+	RETVAL_TRUE;
+
+	status = gss_release_buffer(&minor_status, &output);
+	ASSERT_GSS_SUCCESS(status,minor_status,);
+} /* }}} */
+
+/* {{{ proto bool GSSAPIContext::unwrap( string $input, string &$output)
+   Verifies an input token with an attached MIC and possibly decrypts the message */
+PHP_METHOD(GSSAPIContext, unwrap)
+{
+
+	OM_uint32 status = 0;
+	OM_uint32 minor_status = 0;
+	gss_buffer_desc input;
+	gss_buffer_desc output;
+	zval *zoutput;
+	krb5_gssapi_context_object *context = KRB5_THIS_GSSAPI_CONTEXT;
+	strsize_t input_length = 0;
+
+	memset(&input, 0 , sizeof(input));
+	memset(&output, 0 , sizeof(output));
+
+#if PHP_MAJOR_VERSION >= 7
+	const char *args = "sz/";
+#else
+	const char *args = "sz";
+#endif
+
+	if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, args,
+			&(input.value), &input_length,
+			&zoutput) == FAILURE) {
+		return;
+	}
+	input.length = input_length;
+
+	RETVAL_FALSE;
+
+	status =  gss_unwrap (
+	     &minor_status,
+	     context->context,
+	     &input,
+	     &output,
+	     NULL,
+	     NULL);
+
+	ASSERT_GSS_SUCCESS(status,minor_status,);
+
+	if(zoutput) {
+		zval_dtor(zoutput);
+		_ZVAL_STRINGL(zoutput, output.value, output.length);
+	}
+
+	RETVAL_TRUE;
+
+	status = gss_release_buffer(&minor_status, &output);
+	ASSERT_GSS_SUCCESS(status,minor_status,);
+} /* }}} */

Copied: pecl/krb5/tags/krb5-1.1.0/trunk/kadm.c (from rev 339675, \
pecl/krb5/trunk/kadm.c) \
                ===================================================================
--- pecl/krb5/tags/krb5-1.1.0/trunk/kadm.c	                        (rev 0)
+++ pecl/krb5/tags/krb5-1.1.0/trunk/kadm.c	2016-07-16 14:46:31 UTC (rev 339676)
@@ -0,0 +1,665 @@
+/**
+* Copyright (c) 2008 Moritz Bechler
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+* THE SOFTWARE.
+**/
+
+#include "php_krb5.h"
+#include "php_krb5_kadm.h"
+#include "compat.h"
+
+
+
+zend_object_handlers krb5_kadm5_handlers;
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_KADM5__construct, 0, 0, 2)
+	ZEND_ARG_INFO(0, principal)
+	ZEND_ARG_INFO(0, credentials)
+	ZEND_ARG_INFO(0, use_keytab)
+	ZEND_ARG_ARRAY_INFO(0, config, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_KADM5_getPrincipal, 0, 0, 1)
+	ZEND_ARG_INFO(0, principal)
+	ZEND_ARG_INFO(0, noload)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_KADM5_getPrincipals, 0, 0, 0)
+	ZEND_ARG_INFO(0, filter)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_KADM5_createPrincipal, 0, 0, 1)
+	ZEND_ARG_OBJ_INFO(0, principal, KADM5Principal, 0)
+	ZEND_ARG_INFO(0, password)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_KADM5_getPolicy, 0, 0, 1)
+	ZEND_ARG_INFO(0, policy)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_KADM5_createPolicy, 0, 0, 1)
+	ZEND_ARG_OBJ_INFO(0, policy, KADM5Policy, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_KADM5_getPolicies, 0, 0, 0)
+	ZEND_ARG_INFO(0, filter)
+ZEND_END_ARG_INFO()
+
+
+
+static zend_function_entry krb5_kadm5_functions[] = {
+	PHP_ME(KADM5, __construct,     arginfo_KADM5__construct,      ZEND_ACC_CTOR | \
ZEND_ACC_PUBLIC) +	PHP_ME(KADM5, getPrincipal,    arginfo_KADM5_getPrincipal,    \
ZEND_ACC_PUBLIC) +	PHP_ME(KADM5, getPrincipals,   arginfo_KADM5_getPrincipals,   \
ZEND_ACC_PUBLIC) +	PHP_ME(KADM5, createPrincipal, arginfo_KADM5_createPrincipal, \
ZEND_ACC_PUBLIC) +	PHP_ME(KADM5, getPolicy,       arginfo_KADM5_getPolicy,       \
ZEND_ACC_PUBLIC) +	PHP_ME(KADM5, createPolicy,    arginfo_KADM5_createPolicy,    \
ZEND_ACC_PUBLIC) +	PHP_ME(KADM5, getPolicies,     arginfo_KADM5_getPolicies,     \
ZEND_ACC_PUBLIC) +	PHP_FE_END
+};
+
+/* KADM5 ctor/dtor */
+
+/* {{{ */
+void php_krb5_free_kadm5_object(krb5_kadm5_object *obj) {
+	if(obj) {
+		kadm5_destroy(&obj->handle);
+		if ( obj->config.realm != NULL ) {
+			efree(obj->config.realm);
+		}
+
+		if ( obj->config.admin_server != NULL ) {
+			efree(obj->config.admin_server);
+		}
+
+		krb5_free_context(obj->ctx);
+		efree(obj);
+	}
+}
+/* }}} */
+
+/* {{{ */
+#if PHP_MAJOR_VERSION < 7
+static void php_krb5_kadm5_object_dtor(void *obj, zend_object_handle handle \
TSRMLS_DC) +{
+	krb5_kadm5_object *object = (krb5_kadm5_object*)obj;
+	zend_object_std_dtor(&(object->std) TSRMLS_CC);
+	php_krb5_free_kadm5_object(object);
+}
+#else
+static void php_krb5_kadm5_object_free(zend_object *obj TSRMLS_DC)
+{
+	krb5_kadm5_object *object = (krb5_kadm5_object*)((char *)obj - \
XtOffsetOf(krb5_kadm5_object, std)); +	kadm5_destroy(&object->handle);
+	if ( object->config.realm != NULL ) {
+		efree(object->config.realm);
+	}
+
+	if ( object->config.admin_server != NULL ) {
+		efree(object->config.admin_server);
+	}
+	if ( object->ctx ) {
+		krb5_free_context(object->ctx);
+		object->ctx = NULL;
+	}
+	zend_object_std_dtor(obj);
+}
+#endif
+/* }}} */
+
+/* {{{ */
+#if PHP_MAJOR_VERSION < 7
+zend_object_value php_krb5_kadm5_object_new(zend_class_entry *ce TSRMLS_DC)
+{
+	zend_object_value retval;
+	krb5_kadm5_object *object;
+
+	object = emalloc(sizeof(krb5_kadm5_object));
+	memset(&object->config, 0, sizeof (kadm5_config_params));
+
+	zend_object_std_init(&(object->std), ce TSRMLS_CC);
+
+#if PHP_VERSION_ID < 50399
+	zend_hash_copy(object->std.properties, &ce->default_properties,
+					(copy_ctor_func_t) zval_add_ref, NULL,
+					sizeof(zval*));
+#else
+	object_properties_init(&(object->std), ce);
+#endif
+
+	retval.handle = zend_objects_store_put(object, php_krb5_kadm5_object_dtor, NULL, \
NULL TSRMLS_CC); +
+	retval.handlers = &krb5_kadm5_handlers;
+	return retval;
+}
+#else
+zend_object* php_krb5_kadm5_object_new(zend_class_entry *ce TSRMLS_DC)
+{
+	krb5_kadm5_object *object = ecalloc(1, sizeof(krb5_kadm5_object) + \
zend_object_properties_size(ce)); +	zend_object_std_init(&object->std, ce TSRMLS_CC);
+	object_properties_init(&object->std, ce);
+	object->std.handlers = &krb5_kadm5_handlers;
+	return &object->std;
+}
+#endif
+/* }}} */
+
+/* Register classes */
+/* {{{ */
+int php_krb5_kadm5_register_classes(TSRMLS_D) {
+	zend_class_entry kadm5;
+
+	/** register KADM5 **/
+	INIT_CLASS_ENTRY(kadm5, "KADM5", krb5_kadm5_functions);
+	krb5_ce_kadm5 = zend_register_internal_class(&kadm5 TSRMLS_CC);
+	krb5_ce_kadm5->create_object = php_krb5_kadm5_object_new;
+	memcpy(&krb5_kadm5_handlers, zend_get_std_object_handlers(), \
sizeof(zend_object_handlers)); +#if PHP_MAJOR_VERSION >= 7
+	krb5_kadm5_handlers.offset = XtOffsetOf(krb5_kadm5_object, std);
+	krb5_kadm5_handlers.free_obj = php_krb5_kadm5_object_free;
+#endif
+
+	/** register KADM5Principal **/
+	php_krb5_register_kadm5_principal(TSRMLS_C);
+
+	/** register KADM5Policy **/
+	php_krb5_register_kadm5_policy(TSRMLS_C);
+
+	/** register KADM5TLData **/
+	php_krb5_register_kadm5_tldata(TSRMLS_C);
+
+	return SUCCESS;
+}
+/* }}} */
+
+static int php_krb5_kadm_parse_config(kadm5_config_params *kadm_params, zval *config \
TSRMLS_DC) { +	int retval = 0;
+	zval *tmp = NULL;
+
+	if (Z_TYPE_P(config) != IS_ARRAY) {
+		return KRB5KRB_ERR_GENERIC;
+	}
+
+	/* realm */
+	tmp = zend_compat_hash_find(HASH_OF(config), "realm", sizeof("realm"));
+	if ( tmp != NULL ) {
+		zend_string *realm = zval_get_string(tmp TSRMLS_CC);
+		if ((kadm_params->realm = emalloc(1+realm->len))) {
+			strncpy(kadm_params->realm, realm->val, realm->len);
+			kadm_params->realm[realm->len] = '\0';
+		}
+		zend_string_release(realm);
+		kadm_params->mask |= KADM5_CONFIG_REALM;
+	}
+
+	/* admin_server */
+	tmp = zend_compat_hash_find(HASH_OF(config), "admin_server", \
sizeof("admin_server")); +	if (tmp != NULL) {
+		zend_string *admin_server = zval_get_string(tmp TSRMLS_CC);
+		if ((kadm_params->admin_server = emalloc(1+admin_server->len))) {
+			strncpy(kadm_params->admin_server, admin_server->val, admin_server->len);
+			kadm_params->admin_server[admin_server->len] = '\0';
+                }
+		zend_string_release(admin_server);
+		kadm_params->mask |= KADM5_CONFIG_ADMIN_SERVER;
+	}
+
+	/* admin_port */
+	tmp = zend_compat_hash_find(HASH_OF(config), "kadmind_port", \
sizeof("kadmind_port")); +	if (tmp != NULL) {
+		kadm_params->kadmind_port = zval_get_long(tmp TSRMLS_CC);
+		kadm_params->mask |= KADM5_CONFIG_KADMIND_PORT;
+	}
+
+	return retval;
+}
+
+/* {{{ proto KADM5::__construct(string $principal, string $credentials [, bool \
$use_keytab=0 [, array $config]]) +	Initialize a connection with the KADM server \
using the given credentials */ +PHP_METHOD(KADM5, __construct)
+{
+	kadm5_ret_t retval;
+
+	char *sprinc;
+	strsize_t sprinc_len;
+
+	char *spass = NULL;
+	strsize_t spass_len;
+
+	zend_bool use_keytab = 0;
+
+	zval* config = NULL;
+	krb5_kadm5_object *obj;
+
+	KRB5_SET_ERROR_HANDLING(EH_THROW);
+	if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|ba", &sprinc, &sprinc_len,
+					&spass, &spass_len,
+					&use_keytab, &config) == FAILURE) {
+		RETURN_FALSE;
+	}
+	KRB5_SET_ERROR_HANDLING(EH_NORMAL);
+
+	if(strlen(spass) == 0) {
+		zend_throw_exception(NULL, "You may not specify an empty password or keytab", 0 \
TSRMLS_CC); +		RETURN_FALSE;
+	}
+
+	obj = KRB5_THIS_KADM;
+
+
+	if (config != NULL && php_krb5_kadm_parse_config(&(obj->config), config TSRMLS_CC)) \
{ +		zend_throw_exception(NULL, "Failed to parse kadmin config", 0 TSRMLS_CC);
+		RETURN_FALSE;
+	}
+
+	if(krb5_init_context(&obj->ctx)) {
+		zend_throw_exception(NULL, "Failed to initialize kerberos library", 0 TSRMLS_CC);
+		RETURN_FALSE;
+	}
+
+
+	if(!use_keytab) {
+ 		retval = kadm5_init_with_password(obj->ctx, sprinc, spass, KADM5_ADMIN_SERVICE, \
&obj->config, + 						KADM5_STRUCT_VERSION, KADM5_API_VERSION_2, NULL, &obj->handle);
+ 	} else {
+
+		if (strlen(spass) != spass_len) {
+			zend_throw_exception(NULL, "Invalid keytab path", 0 TSRMLS_CC);
+			krb5_free_context(obj->ctx);
+			obj->ctx = NULL;
+			RETURN_FALSE;
+		}
+#if PHP_VERSION_ID < 50399
+  		if((PG(safe_mode) && !php_checkuid(spass, NULL, CHECKUID_CHECK_FILE_AND_DIR)) ||
+  			php_check_open_basedir(spass TSRMLS_CC)) {
+			krb5_free_context(obj->ctx);
+			obj->ctx = NULL;
+  			RETURN_FALSE;
+  		}
+#else
+  		if( php_check_open_basedir(spass TSRMLS_CC)) {
+			krb5_free_context(obj->ctx);
+			obj->ctx = NULL;
+  			RETURN_FALSE;
+  		}
+#endif
+
+ 		retval = kadm5_init_with_skey(obj->ctx,sprinc, spass, KADM5_ADMIN_SERVICE, \
&obj->config, + 						KADM5_STRUCT_VERSION, KADM5_API_VERSION_2, NULL, &obj->handle);
+	}
+
+	if(retval != KADM5_OK) {
+		const char* errmsg = krb5_get_error_message(obj->ctx, (int)retval);
+		zend_throw_exception(NULL, errmsg, (int)retval TSRMLS_CC);
+		krb5_free_error_message(obj->ctx, errmsg);
+		krb5_free_context(obj->ctx);
+		obj->ctx = NULL;
+		RETURN_FALSE;
+	}
+
+	RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto KADM5Principal KADM5::getPrinicipal(string $principal [, boolean \
$noload ]) +	Fetch a principal entry by name */
+PHP_METHOD(KADM5, getPrincipal)
+{
+
+
+	zval *sprinc = NULL;
+	zend_bool noload = FALSE;
+
+	if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|b", &sprinc, &noload) == \
FAILURE) { +		RETURN_FALSE;
+	}
+
+	object_init_ex(return_value, krb5_ce_kadm5_principal);
+
+#if PHP_MAJOR_VERSION < 7
+	zval *dummy_retval, *ctor, *znoload;
+	zval *args[3];
+	MAKE_STD_ZVAL(ctor);
+	ZVAL_STRING(ctor, "__construct",1);
+	MAKE_STD_ZVAL(znoload);
+	ZVAL_BOOL(znoload, noload);
+
+
+	args[0] = sprinc;
+	args[1] = getThis();
+	args[2] = znoload;
+
+	MAKE_STD_ZVAL(dummy_retval);
+	if(call_user_function(&krb5_ce_kadm5_principal->function_table,
+							&return_value, ctor, dummy_retval, 3,
+							args TSRMLS_CC) == FAILURE) {
+		zval_dtor(ctor);
+		zval_dtor(dummy_retval);
+		zend_throw_exception(NULL, "Failed to instantiate KADM5Principal object", 0 \
TSRMLS_CC); +	}
+
+	zval_ptr_dtor(&ctor);
+	zval_ptr_dtor(&dummy_retval);
+	zval_ptr_dtor(&znoload);
+#else
+	zval ctor;
+	zval args[3];
+	zval dummy_retval;
+	ZVAL_STRING(&ctor, "__construct");
+	args[0] = *sprinc;
+	args[1] = *getThis();
+	ZVAL_BOOL(&args[2], noload);
+	if(call_user_function(&krb5_ce_kadm5_principal->function_table, return_value, \
&ctor, &dummy_retval, 3, +							args TSRMLS_CC) == FAILURE) {
+		zval_dtor(&ctor);
+		zval_dtor(&dummy_retval);
+		zval_dtor(&args[2]);
+		zend_throw_exception(NULL, "Failed to instantiate KADM5Principal object", 0 \
TSRMLS_CC); +		return;
+	}
+	zval_dtor(&ctor);
+	zval_dtor(&dummy_retval);
+	zval_dtor(&args[2]);
+#endif
+} /* }}} */
+
+/* {{{ proto array KADM5::getPrinicipals([string $filter])
+	Fetch an array of all principals matching $filter */
+PHP_METHOD(KADM5, getPrincipals)
+{
+	kadm5_ret_t retval;
+	krb5_kadm5_object *obj;
+
+	char *sexp = NULL;
+	strsize_t sexp_len;
+
+	char **princs;
+	int princ_count;
+
+	int i;
+
+	if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &sexp, &sexp_len) == \
FAILURE) { +		RETURN_FALSE;
+	}
+
+	obj = KRB5_THIS_KADM;
+	retval = kadm5_get_principals(obj->handle, sexp, &princs, &princ_count);
+
+	if(retval) {
+		const char *errmsg = krb5_get_error_message(obj->ctx, (int)retval);
+		zend_throw_exception(NULL, errmsg, (int)retval TSRMLS_CC);
+		krb5_free_error_message(obj->ctx, errmsg);
+		return;
+	}
+
+	array_init(return_value);
+
+	for(i = 0; i < princ_count; i++) {
+		_add_next_index_string(return_value, princs[i]);
+	}
+
+	kadm5_free_name_list(obj->handle, princs, princ_count);
+} /* }}} */
+
+/* {{{ proto void KADM5::createPrincipal(KADM5Principal $principal [, string \
$password ]) +	Creates a principal */
+PHP_METHOD(KADM5, createPrincipal)
+{
+	kadm5_ret_t retval = 0;
+	zval *princ = NULL, *princname = NULL;
+	krb5_kadm5_principal_object *principal = NULL;
+	krb5_kadm5_object *obj = NULL;
+
+
+	char *pw = NULL;
+	strsize_t pw_len = 0;
+
+	if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|s", &princ, \
krb5_ce_kadm5_principal, &pw, &pw_len) == FAILURE) { +		return;
+	}
+
+	if ( Z_ISNULL_P(princ) ) {
+		zend_throw_exception(NULL, "Invalid principal object", 0 TSRMLS_CC);
+		return;
+	}
+
+	principal = KRB5_KADM_PRINCIPAL(princ);
+	obj = KRB5_THIS_KADM;
+
+#if PHP_MAJOR_VERSION < 7
+	princname = zend_read_property(krb5_ce_kadm5_principal, princ, "princname",
+									sizeof("princname"),1 TSRMLS_CC);
+#else
+	princname = zend_read_property(krb5_ce_kadm5_principal, princ, "princname",
+									sizeof("princname"),1, NULL TSRMLS_CC);
+#endif
+	if ( principal->data.principal ) {
+		krb5_free_principal(obj->ctx, principal->data.principal);
+	}
+
+	zend_string *pnamestr = zval_get_string(princname TSRMLS_CC);
+	if(krb5_parse_name(obj->ctx, pnamestr->val, &principal->data.principal)) {
+		zend_string_release(pnamestr);
+		zend_throw_exception(NULL, "Failed to parse principal name", 0 TSRMLS_CC);
+		return;
+	}
+	zend_string_release(pnamestr);
+	principal->update_mask |= KADM5_PRINCIPAL;
+	principal->conn = obj;
+	zend_update_property(krb5_ce_kadm5_principal, princ, "connection", \
sizeof("connection"), getThis() TSRMLS_CC); +
+	retval = kadm5_create_principal(obj->handle, &principal->data, \
principal->update_mask, pw); +	if(retval != KADM5_OK) {
+		const char* errmsg =  krb5_get_error_message(obj->ctx, (int)retval);
+		zend_throw_exception(NULL, errmsg, (int)retval TSRMLS_CC);
+		krb5_free_error_message(obj->ctx, errmsg);
+		return;
+	}
+
+
+#if PHP_MAJOR_VERSION < 7
+	zval *dummy_retval = NULL, *func = NULL;
+	MAKE_STD_ZVAL(func);
+	ZVAL_STRING(func, "load", 1);
+	MAKE_STD_ZVAL(dummy_retval);
+	if(call_user_function(&krb5_ce_kadm5_principal->function_table,
+							&princ, func, dummy_retval, 0,
+							NULL TSRMLS_CC) == FAILURE) {
+
+		zval_ptr_dtor(&func);
+		zval_ptr_dtor(&dummy_retval);
+
+		zend_throw_exception(NULL, "Failed to update KADM5Principal object", 0 TSRMLS_CC);
+		return;
+	}
+
+	zval_ptr_dtor(&func);
+	zval_ptr_dtor(&dummy_retval);
+#else
+	zval func;
+	zval dummy_retval;
+	ZVAL_STRING(&func, "load");
+	if(call_user_function(&krb5_ce_kadm5_principal->function_table, princ, &func, \
&dummy_retval, 0, +							NULL TSRMLS_CC) == FAILURE) {
+		zval_dtor(&func);
+		zval_dtor(&dummy_retval);
+		zend_throw_exception(NULL, "Failed to update KADM5Principal object", 0 TSRMLS_CC);
+		return;
+	}
+	zval_dtor(&func);
+	zval_dtor(&dummy_retval);
+#endif
+}
+
+/* {{{ proto KADM5Policy KADM5::getPolicy(string $policy)
+	Fetches a policy */
+PHP_METHOD(KADM5, getPolicy)
+{
+
+
+	zval *spolicy = NULL;
+
+	if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &spolicy) == FAILURE) {
+		return;
+	}
+
+	object_init_ex(return_value, krb5_ce_kadm5_policy);
+
+#if PHP_MAJOR_VERSION < 7
+	zval *dummy_retval, *ctor;
+	zval *args[2];
+	MAKE_STD_ZVAL(ctor);
+	ZVAL_STRING(ctor, "__construct", 1);
+
+	args[0] = spolicy;
+	args[1] = getThis();
+
+	MAKE_STD_ZVAL(dummy_retval);
+	if(call_user_function(&krb5_ce_kadm5_policy->function_table,
+							&return_value, ctor, dummy_retval, 2,
+							args TSRMLS_CC) == FAILURE) {
+		zval_dtor(ctor);
+		zval_dtor(dummy_retval);
+		zend_throw_exception(NULL, "Failed to instantiate KADM5Policy object", 0 \
TSRMLS_CC); +		return;
+	}
+
+	zval_ptr_dtor(&ctor);
+	zval_ptr_dtor(&dummy_retval);
+#else
+	zval ctor;
+	zval args[2];
+	zval dummy_retval;
+	ZVAL_STRING(&ctor, "__construct");
+	args[0] = *spolicy;
+	args[1] = *getThis();
+	if(call_user_function(&krb5_ce_kadm5_policy->function_table, return_value, &ctor, \
&dummy_retval, 2, +							args TSRMLS_CC) == FAILURE) {
+		zval_dtor(&ctor);
+		zval_dtor(&dummy_retval);
+		zend_throw_exception(NULL, "Failed to instantiate KADM5Policy object", 0 \
TSRMLS_CC); +		return;
+	}
+	zval_dtor(&ctor);
+	zval_dtor(&dummy_retval);
+#endif
+} /* }}} */
+
+/* {{{ proto void KADM5::createPolicy(KADM5Policy $policy)
+	Creates a Policy */
+PHP_METHOD(KADM5, createPolicy) {
+	kadm5_ret_t retval;
+	zval *zpolicy;
+	krb5_kadm5_policy_object *policy;
+	krb5_kadm5_object *obj;
+
+
+
+	if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &zpolicy, \
krb5_ce_kadm5_policy) == FAILURE) { +		return;
+	}
+
+	policy = KRB5_KADM_POLICY(zpolicy);
+	obj = KRB5_THIS_KADM;
+
+	policy->update_mask |= KADM5_POLICY;
+	policy->conn = obj;
+	policy->data.policy = policy->policy;
+	zend_update_property(krb5_ce_kadm5_policy, zpolicy, "connection", \
sizeof("connection"), getThis() TSRMLS_CC); +
+	retval = kadm5_create_policy(obj->handle, &policy->data, policy->update_mask);
+	if(retval != KADM5_OK) {
+		policy->data.policy = NULL;
+		const char* errmsg = krb5_get_error_message(obj->ctx, (int)retval);
+		zend_throw_exception(NULL, errmsg, (int)retval TSRMLS_CC);
+		krb5_free_error_message(obj->ctx, errmsg);
+		return;
+	}
+
+	policy->data.policy = NULL;
+
+#if PHP_MAJOR_VERSION < 7
+	zval *dummy_retval, *func;
+	MAKE_STD_ZVAL(func);
+	ZVAL_STRING(func, "load", 1);
+	MAKE_STD_ZVAL(dummy_retval);
+	if(call_user_function(&krb5_ce_kadm5_policy->function_table,
+							&zpolicy, func, dummy_retval, 0,
+							NULL TSRMLS_CC) == FAILURE) {
+		zval_ptr_dtor(&func);
+		zval_ptr_dtor(&dummy_retval);
+		zend_throw_exception(NULL, "Failed to update KADM5Policy object", 0 TSRMLS_CC);
+		return;
+	}
+
+	zval_ptr_dtor(&func);
+	zval_ptr_dtor(&dummy_retval);
+#else
+	zval func;
+	zval dummy_retval;
+	ZVAL_STRING(&func, "load");
+	if(call_user_function(&krb5_ce_kadm5_policy->function_table, zpolicy, &func, \
&dummy_retval, 0, +							NULL TSRMLS_CC) == FAILURE) {
+		zval_dtor(&func);
+		zval_dtor(&dummy_retval);
+		zend_throw_exception(NULL, "Failed to update KADM5Policy object", 0 TSRMLS_CC);
+		return;
+	}
+	zval_dtor(&func);
+	zval_dtor(&dummy_retval);
+#endif
+} /* }}} */
+
+/* {{{ proto array KADM5::getPolicies([string $filter])
+	Fetches all policies */
+PHP_METHOD(KADM5, getPolicies)
+{
+	kadm5_ret_t retval;
+	krb5_kadm5_object *obj;
+
+	char *sexp = NULL;
+	strsize_t sexp_len;
+
+	char **policies;
+	int pol_count;
+
+	int i;
+
+	if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &sexp, &sexp_len) == \
FAILURE) { +		RETURN_FALSE;
+	}
+
+	obj = KRB5_THIS_KADM;
+	retval = kadm5_get_policies(obj->handle, sexp, &policies, &pol_count);
+
+	if(retval) {
+		const char* errmsg =  krb5_get_error_message(obj->ctx, (int)retval);
+		zend_throw_exception(NULL, errmsg, (int)retval TSRMLS_CC);
+		krb5_free_error_message(obj->ctx, errmsg);
+		return;
+	}
+
+	array_init(return_value);
+
+	for(i = 0; i < pol_count; i++) {
+		_add_next_index_string(return_value, policies[i]);
+	}
+
+	kadm5_free_name_list(obj->handle, policies, pol_count);
+} /* }}} */

Copied: pecl/krb5/tags/krb5-1.1.0/trunk/kadm5_policy.c (from rev 339675, \
pecl/krb5/trunk/kadm5_policy.c) \
                ===================================================================
--- pecl/krb5/tags/krb5-1.1.0/trunk/kadm5_policy.c	                        (rev 0)
+++ pecl/krb5/tags/krb5-1.1.0/trunk/kadm5_policy.c	2016-07-16 14:46:31 UTC (rev \
339676) @@ -0,0 +1,525 @@
+/**
+* Copyright (c) 2007 Moritz Bechler
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+* THE SOFTWARE.
+**/
+
+#include "php_krb5.h"
+#include "php_krb5_kadm.h"
+#include "compat.h"
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_KADM5Policy_none, 0, 0, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_KADM5Policy__construct, 0, 0, 1)
+	ZEND_ARG_INFO(0, policy)
+	ZEND_ARG_OBJ_INFO(0, conn, KADM5, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_KADM5Policy_setMinPasswordLife, 0, 0, 1)
+	ZEND_ARG_INFO(0, min_life)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_KADM5Policy_setMaxPasswordLife, 0, 0, 1)
+	ZEND_ARG_INFO(0, max_life)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_KADM5Policy_setMinPasswordLength, 0, 0, 1)
+	ZEND_ARG_INFO(0, min_length)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_KADM5Policy_setMinPasswordClasses, 0, 0, 1)
+	ZEND_ARG_INFO(0, min_classes)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_KADM5Policy_setHistoryNum, 0, 0, 1)
+	ZEND_ARG_INFO(0, history_num)
+ZEND_END_ARG_INFO()
+
+static zend_function_entry krb5_kadm5_policy_functions[] = {
+	PHP_ME(KADM5Policy, __construct,           arginfo_KADM5Policy__construct,          \
ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) +	PHP_ME(KADM5Policy, load,                  \
arginfo_KADM5Policy_none,                  ZEND_ACC_PUBLIC) +	PHP_ME(KADM5Policy, \
save,                  arginfo_KADM5Policy_none,                  ZEND_ACC_PUBLIC) \
+	PHP_ME(KADM5Policy, delete,                arginfo_KADM5Policy_none,                \
ZEND_ACC_PUBLIC) +	PHP_ME(KADM5Policy, getPropertyArray,      \
arginfo_KADM5Policy_none,                  ZEND_ACC_PUBLIC) +	PHP_ME(KADM5Policy, \
getName,               arginfo_KADM5Policy_none,                  ZEND_ACC_PUBLIC) \
+	PHP_ME(KADM5Policy, getMinPasswordLife,    arginfo_KADM5Policy_none,                \
ZEND_ACC_PUBLIC) +	PHP_ME(KADM5Policy, setMinPasswordLife,    \
arginfo_KADM5Policy_setMinPasswordLife,    ZEND_ACC_PUBLIC) +	PHP_ME(KADM5Policy, \
getMaxPasswordLife,    arginfo_KADM5Policy_none,                  ZEND_ACC_PUBLIC) \
+	PHP_ME(KADM5Policy, setMaxPasswordLife,    arginfo_KADM5Policy_setMaxPasswordLife,  \
ZEND_ACC_PUBLIC) +	PHP_ME(KADM5Policy, getMinPasswordLength,  \
arginfo_KADM5Policy_none,                  ZEND_ACC_PUBLIC) +	PHP_ME(KADM5Policy, \
setMinPasswordLength,  arginfo_KADM5Policy_setMinPasswordLength,  ZEND_ACC_PUBLIC) \
+	PHP_ME(KADM5Policy, getMinPasswordClasses, arginfo_KADM5Policy_none,                \
ZEND_ACC_PUBLIC) +	PHP_ME(KADM5Policy, setMinPasswordClasses, \
arginfo_KADM5Policy_setMinPasswordClasses, ZEND_ACC_PUBLIC) +	PHP_ME(KADM5Policy, \
getHistoryNum,         arginfo_KADM5Policy_none,                  ZEND_ACC_PUBLIC) \
+	PHP_ME(KADM5Policy, setHistoryNum,         arginfo_KADM5Policy_setHistoryNum,       \
ZEND_ACC_PUBLIC) +	PHP_ME(KADM5Policy, getReferenceCount,     \
arginfo_KADM5Policy_none,                  ZEND_ACC_PUBLIC) +	PHP_FE_END
+};
+
+zend_object_handlers krb5_kadm5_policy_handlers;
+
+#if PHP_MAJOR_VERSION < 7
+static void php_krb5_kadm5_policy_object_dtor(void *obj, zend_object_handle handle \
TSRMLS_DC) +{
+	krb5_kadm5_policy_object *object = (krb5_kadm5_policy_object*)obj;
+
+
+	if(object->policy) {
+		efree(object->policy);
+	}
+
+	krb5_kadm5_object *conn = object->conn;
+	if(conn) {
+		kadm5_free_policy_ent(conn->handle, &object->data);
+	}
+	zend_object_std_dtor(&(object->std) TSRMLS_CC);
+	efree(object);
+}
+#else
+static void php_krb5_kadm5_policy_object_free(zend_object *obj) {
+	krb5_kadm5_policy_object *object = (krb5_kadm5_policy_object*)((char *)obj - \
XtOffsetOf(krb5_kadm5_policy_object, std)); +	krb5_kadm5_object *conn = object->conn;
+	if(object->policy) {
+		efree(object->policy);
+	}
+	if(conn) {
+			kadm5_free_policy_ent(conn->handle, &object->data);
+	}
+	zend_object_std_dtor(obj);
+}
+#endif
+
+int php_krb5_register_kadm5_policy(TSRMLS_D) {
+	zend_class_entry kadm5_policy;
+	INIT_CLASS_ENTRY(kadm5_policy, "KADM5Policy", krb5_kadm5_policy_functions);
+	krb5_ce_kadm5_policy = zend_register_internal_class(&kadm5_policy TSRMLS_CC);
+	krb5_ce_kadm5_policy->create_object = php_krb5_kadm5_policy_object_new;
+	memcpy(&krb5_kadm5_policy_handlers, zend_get_std_object_handlers(), \
sizeof(zend_object_handlers)); +#if PHP_MAJOR_VERSION >= 7
+	krb5_kadm5_policy_handlers.offset = XtOffsetOf(krb5_kadm5_policy_object, std);
+	krb5_kadm5_policy_handlers.free_obj = php_krb5_kadm5_policy_object_free;
+#endif
+	return SUCCESS;
+}
+
+
+#if PHP_MAJOR_VERSION < 7
+zend_object_value php_krb5_kadm5_policy_object_new(zend_class_entry *ce TSRMLS_DC)
+{
+	zend_object_value retval;
+	krb5_kadm5_policy_object *object;
+	extern zend_object_handlers krb5_kadm5_policy_handlers;
+
+	object = emalloc(sizeof(krb5_kadm5_policy_object));
+
+	memset(&object->data, 0, sizeof(kadm5_policy_ent_rec));
+	object->conn = NULL;
+	object->update_mask = 0;
+
+	zend_object_std_init(&(object->std), ce TSRMLS_CC);
+
+#if PHP_VERSION_ID < 50399
+	zend_hash_copy(object->std.properties, &ce->default_properties,
+					(copy_ctor_func_t) zval_add_ref, NULL,
+					sizeof(zval*));
+#else
+	object_properties_init(&(object->std), ce);
+#endif
+
+	retval.handle = zend_objects_store_put(object, php_krb5_kadm5_policy_object_dtor, \
NULL, NULL TSRMLS_CC); +
+	retval.handlers = &krb5_kadm5_policy_handlers;
+	return retval;
+}
+#else
+zend_object* php_krb5_kadm5_policy_object_new(zend_class_entry *ce TSRMLS_DC) {
+	krb5_kadm5_policy_object *object = ecalloc(1, sizeof(krb5_kadm5_policy_object) + \
zend_object_properties_size(ce)); +	zend_object_std_init(&object->std, ce TSRMLS_CC);
+	object_properties_init(&object->std, ce);
+	object->std.handlers = &krb5_kadm5_policy_handlers;
+	return &object->std;
+}
+#endif
+
+/* {{{ proto KADM5Policy::__construct(string $policy [, KADM5 $conn ])
+ */
+PHP_METHOD(KADM5Policy, __construct)
+{
+	krb5_kadm5_policy_object *this = KRB5_THIS_KADM_POLICY;
+	char *spolicy = NULL;
+	strsize_t spolicy_len;
+
+	krb5_kadm5_policy_object *obj;
+
+	zval *connobj = NULL;
+
+
+	KRB5_SET_ERROR_HANDLING(EH_THROW);
+	if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|O", &spolicy, &spolicy_len, \
&connobj, krb5_ce_kadm5) == FAILURE) { +		RETURN_NULL();
+	}
+	KRB5_SET_ERROR_HANDLING(EH_NORMAL);
+
+	obj = KRB5_THIS_KADM_POLICY;
+	obj->policy = estrndup(spolicy, spolicy_len);
+
+	if(connobj && Z_TYPE_P(connobj) == IS_OBJECT) {
+		zend_update_property(krb5_ce_kadm5_principal, getThis(), "connection", \
sizeof("connection"), connobj TSRMLS_CC); +		this->conn = KRB5_KADM(connobj);
+
+#if PHP_MAJOR_VERSION < 7
+		zval *dummy_retval, *func;
+		MAKE_STD_ZVAL(func);
+		_ZVAL_STRING(func, "load");
+		MAKE_STD_ZVAL(dummy_retval);
+		if(call_user_function(&krb5_ce_kadm5_policy->function_table,
+								&getThis(), func, dummy_retval, 0,
+								NULL TSRMLS_CC) == FAILURE) {
+			zval_ptr_dtor(&func);
+			zval_ptr_dtor(&dummy_retval);
+			zend_throw_exception(NULL, "Failed to update KADM5Policy object", 0 TSRMLS_CC);
+			return;
+		}
+
+		zval_ptr_dtor(&func);
+		zval_ptr_dtor(&dummy_retval);
+#else
+		zval func;
+		zval dummy_retval;
+		_ZVAL_STRING(&func, "load");
+		if(call_user_function(&krb5_ce_kadm5_policy->function_table, getThis(), &func, \
&dummy_retval, 0, +								NULL TSRMLS_CC) == FAILURE) {
+			zval_ptr_dtor(&func);
+			zval_ptr_dtor(&dummy_retval);
+			zend_throw_exception(NULL, "Failed to update KADM5Policy object", 0 TSRMLS_CC);
+			return;
+		}
+		zval_ptr_dtor(&func);
+		zval_ptr_dtor(&dummy_retval);
+#endif
+	}
+}
+/* }}} */
+
+#if PHP_MAJOR_VERSION < 7
+#define KRB5_KADM_POLICY_GET_CONNECTION zend_read_property(krb5_ce_kadm5_policy, \
getThis(), "connection", sizeof("connection"),1 TSRMLS_CC); +#else
+#define KRB5_KADM_POLICY_GET_CONNECTION zend_read_property(krb5_ce_kadm5_policy, \
getThis(), "connection", sizeof("connection"),1, NULL TSRMLS_CC); +#endif
+
+/* {{{ proto KADM5Policy::load()
+ */
+PHP_METHOD(KADM5Policy, load)
+{
+	kadm5_ret_t retval;
+	krb5_kadm5_policy_object *obj = KRB5_THIS_KADM_POLICY;
+	krb5_kadm5_object *kadm5;
+	zval *connobj = NULL;
+
+	if (zend_parse_parameters_none() == FAILURE) {
+		return;
+	}
+	connobj = KRB5_KADM_POLICY_GET_CONNECTION;
+	if ( Z_ISNULL_P(connobj) ) {
+		zend_throw_exception(NULL, "No valid connection available", 0 TSRMLS_CC);
+		return;
+	}
+
+	kadm5 = KRB5_KADM(connobj);
+	if(!kadm5) {
+		zend_throw_exception(NULL, "No valid connection available", 0 TSRMLS_CC);
+		return;
+	}
+
+	retval = kadm5_get_policy(kadm5->handle, obj->policy, &obj->data);
+	if(retval != KADM5_OK || !obj->data.policy) {
+		const char *errmsg = krb5_get_error_message(kadm5->ctx, (int)retval);
+		zend_throw_exception(NULL, errmsg, (int)retval TSRMLS_CC);
+		krb5_free_error_message(kadm5->ctx, errmsg);
+		return;
+	}
+}
+/* }}} */
+
+/* {{{ proto KADM5Policy::save()
+ */
+PHP_METHOD(KADM5Policy, save)
+{
+	kadm5_ret_t retval;
+	krb5_kadm5_policy_object *obj = KRB5_THIS_KADM_POLICY;
+	krb5_kadm5_object *kadm5;
+	zval *connobj = NULL;
+
+	if (zend_parse_parameters_none() == FAILURE) {
+		return;
+	}
+	connobj = KRB5_KADM_POLICY_GET_CONNECTION;
+	if ( Z_ISNULL_P(connobj) ) {
+		zend_throw_exception(NULL, "No valid connection available", 0 TSRMLS_CC);
+		return;
+	}
+
+	kadm5 = KRB5_KADM(connobj);
+	if(!kadm5) {
+		zend_throw_exception(NULL, "No valid connection available", 0 TSRMLS_CC);
+		return;
+	}
+
+	retval = kadm5_modify_policy(kadm5->handle, &obj->data, obj->update_mask);
+	if(retval != KADM5_OK) {
+		const char *errmsg = krb5_get_error_message(kadm5->ctx, (int)retval);
+		zend_throw_exception(NULL, errmsg, (int)retval TSRMLS_CC);
+		krb5_free_error_message(kadm5->ctx, errmsg);
+		return;
+	}
+}
+/* }}} */
+
+/* {{{ proto KADM5Policy::delete()
+ */
+PHP_METHOD(KADM5Policy, delete)
+{
+	kadm5_ret_t retval;
+	krb5_kadm5_policy_object *obj = KRB5_THIS_KADM_POLICY;
+	krb5_kadm5_object *kadm5;
+	zval *connobj = NULL;
+
+	if (zend_parse_parameters_none() == FAILURE) {
+		return;
+	}
+	connobj = KRB5_KADM_POLICY_GET_CONNECTION;
+	if ( Z_ISNULL_P(connobj) ) {
+		zend_throw_exception(NULL, "No valid connection available", 0 TSRMLS_CC);
+		return;
+	}
+
+	kadm5 = KRB5_KADM(connobj);
+	if(!kadm5) {
+		zend_throw_exception(NULL, "No valid connection available", 0 TSRMLS_CC);
+		return;
+	}
+
+	retval = kadm5_delete_policy(kadm5->handle, obj->policy);
+	if(retval != KADM5_OK) {
+		const char *errmsg = krb5_get_error_message(kadm5->ctx, (int)retval);
+		zend_throw_exception(NULL, errmsg, (int)retval TSRMLS_CC);
+		krb5_free_error_message(kadm5->ctx, errmsg);
+		return;
+	}
+}
+/* }}} */
+
+
+/* {{{ proto KADM5Policy::getPropertyArray()
+ */
+PHP_METHOD(KADM5Policy, getPropertyArray)
+{
+	krb5_kadm5_policy_object *obj = KRB5_THIS_KADM_POLICY;
+
+	if (zend_parse_parameters_none() == FAILURE) {
+		return;
+	}
+	array_init(return_value);
+	_add_assoc_string(return_value, "policy", obj->policy);
+	add_assoc_long(return_value, "pw_min_life", obj->data.pw_min_life);
+	add_assoc_long(return_value, "pw_max_life", obj->data.pw_max_life);
+	add_assoc_long(return_value, "pw_min_length", obj->data.pw_min_length);
+	add_assoc_long(return_value, "pw_min_classes", obj->data.pw_min_classes);
+	add_assoc_long(return_value, "pw_history_num", obj->data.pw_history_num);
+	add_assoc_long(return_value, "policy_refcnt", obj->data.policy_refcnt);
+}
+/* }}} */
+
+/* {{{ proto KADM5Policy::getName()
+ */
+PHP_METHOD(KADM5Policy, getName)
+{
+	krb5_kadm5_policy_object *obj = KRB5_THIS_KADM_POLICY;
+
+	if (zend_parse_parameters_none() == FAILURE) {
+		return;
+	}
+	_RETURN_STRING(obj->policy);
+}
+/* }}} */
+
+/* {{{ proto KADM5Policy::getMinPasswordLife()
+ */
+PHP_METHOD(KADM5Policy, getMinPasswordLife)
+{
+	krb5_kadm5_policy_object *obj = KRB5_THIS_KADM_POLICY;
+
+	if (zend_parse_parameters_none() == FAILURE) {
+		return;
+	}
+	RETURN_LONG(obj->data.pw_min_life);
+}
+/* }}} */
+
+/* {{{ proto KADM5Policy::setMinPasswordLife(int $min_life)
+ */
+PHP_METHOD(KADM5Policy, setMinPasswordLife)
+{
+	krb5_kadm5_policy_object *obj = KRB5_THIS_KADM_POLICY;
+	zend_long min_life;
+
+	if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &min_life) == FAILURE) {
+		RETURN_FALSE;
+	}
+
+	obj->data.pw_min_life = min_life;
+	obj->update_mask |= KADM5_PW_MIN_LIFE;
+	RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto KADM5Policy::getMaxPasswordLife()
+ */
+PHP_METHOD(KADM5Policy, getMaxPasswordLife)
+{
+	krb5_kadm5_policy_object *obj = KRB5_THIS_KADM_POLICY;
+
+	if (zend_parse_parameters_none() == FAILURE) {
+		return;
+	}
+	RETURN_LONG(obj->data.pw_max_life);
+}
+/* }}} */
+
+/* {{{ proto KADM5Policy::setMaxPasswordLife(int $max_life)
+ */
+PHP_METHOD(KADM5Policy, setMaxPasswordLife)
+{
+	krb5_kadm5_policy_object *obj = KRB5_THIS_KADM_POLICY;
+	zend_long max_life;
+
+	if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &max_life) == FAILURE) {
+		RETURN_FALSE;
+	}
+
+	obj->data.pw_max_life = max_life;
+	obj->update_mask |= KADM5_PW_MAX_LIFE;
+	RETURN_TRUE;
+}
+/* }}} */
+
+
+/* {{{ proto KADM5Policy::getMinPasswordLength()
+ */
+PHP_METHOD(KADM5Policy, getMinPasswordLength)
+{
+	krb5_kadm5_policy_object *obj = KRB5_THIS_KADM_POLICY;
+
+	if (zend_parse_parameters_none() == FAILURE) {
+		return;
+	}
+	RETURN_LONG(obj->data.pw_min_length);
+}
+/* }}} */
+
+/* {{{ proto KADM5Policy::setMinPasswordLength(int $min_length)
+ */
+PHP_METHOD(KADM5Policy, setMinPasswordLength)
+{
+	krb5_kadm5_policy_object *obj = KRB5_THIS_KADM_POLICY;
+	zend_long min_length;
+
+	if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &min_length) == FAILURE) {
+		RETURN_FALSE;
+	}
+
+	obj->data.pw_min_length = min_length;
+	obj->update_mask |= KADM5_PW_MIN_LENGTH;
+	RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto KADM5Policy::getMinPasswordClasses()
+ */
+PHP_METHOD(KADM5Policy, getMinPasswordClasses)
+{
+	krb5_kadm5_policy_object *obj = KRB5_THIS_KADM_POLICY;
+
+	if (zend_parse_parameters_none() == FAILURE) {
+		return;
+	}
+	RETURN_LONG(obj->data.pw_min_classes);
+}
+/* }}} */
+
+/* {{{ proto KADM5Policy::setMinPasswordClasses(int $min_classes)
+ */
+PHP_METHOD(KADM5Policy, setMinPasswordClasses)
+{
+	krb5_kadm5_policy_object *obj = KRB5_THIS_KADM_POLICY;
+	zend_long min_classes;
+
+	if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &min_classes) == FAILURE) \
{ +		RETURN_FALSE;
+	}
+
+	obj->data.pw_min_classes = min_classes;
+	obj->update_mask |= KADM5_PW_MIN_CLASSES;
+	RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto KADM5Policy::getHistoryNum()
+ */
+PHP_METHOD(KADM5Policy, getHistoryNum)
+{
+	krb5_kadm5_policy_object *obj = KRB5_THIS_KADM_POLICY;
+
+	if (zend_parse_parameters_none() == FAILURE) {
+		return;
+	}
+	RETURN_LONG(obj->data.pw_history_num);
+}
+/* }}} */
+
+/* {{{ proto KADM5Policy::setHistoryNum(int $history_num)
+ */
+PHP_METHOD(KADM5Policy, setHistoryNum)
+{
+	krb5_kadm5_policy_object *obj = KRB5_THIS_KADM_POLICY;
+	zend_long history_num;
+
+	if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &history_num) == FAILURE) \
{ +		RETURN_FALSE;
+	}
+
+	obj->data.pw_history_num = history_num;
+	obj->update_mask |= KADM5_PW_HISTORY_NUM;
+	RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto KADM5Policy::getReferenceCount()
+ */
+PHP_METHOD(KADM5Policy, getReferenceCount)
+{
+	krb5_kadm5_policy_object *obj = KRB5_THIS_KADM_POLICY;
+
+	if (zend_parse_parameters_none() == FAILURE) {
+		return;
+	}
+	RETURN_LONG(obj->data.policy_refcnt);
+}
+/* }}} */

Copied: pecl/krb5/tags/krb5-1.1.0/trunk/kadm5_principal.c (from rev 339675, \
pecl/krb5/trunk/kadm5_principal.c) \
                ===================================================================
--- pecl/krb5/tags/krb5-1.1.0/trunk/kadm5_principal.c	                        (rev 0)
+++ pecl/krb5/tags/krb5-1.1.0/trunk/kadm5_principal.c	2016-07-16 14:46:31 UTC (rev \
339676) @@ -0,0 +1,1123 @@
+/**
+* Copyright (c) 2007 Moritz Bechler
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+* THE SOFTWARE.
+**/
+
+#include "php_krb5.h"
+#include "php_krb5_kadm.h"
+#include "compat.h"
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_KADM5Principal_none, 0, 0, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_KADM5Principal__construct, 0, 0, 1)
+	ZEND_ARG_INFO(0, principal)
+	ZEND_ARG_OBJ_INFO(0, connection, KADM5, 0)
+	ZEND_ARG_INFO(0, noload)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_KADM5Principal_changePassword, 0, 0, 1)
+	ZEND_ARG_INFO(0, password)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_KADM5Principal_rename, 0, 0, 1)
+	ZEND_ARG_INFO(0, dst_name)
+	ZEND_ARG_INFO(0, dst_pw)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_KADM5Principal_time, 0, 0, 1)
+	ZEND_ARG_INFO(0, time)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_KADM5Principal_setKeyVNO, 0, 0, 1)
+	ZEND_ARG_INFO(0, kvno)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_KADM5Principal_setAttributes, 0, 0, 1)
+	ZEND_ARG_INFO(0, attrs)
+ZEND_END_ARG_INFO()
+
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_KADM5Principal_setPolicy, 0, 0, 1)
+	ZEND_ARG_INFO(0, policy)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_KADM5Principal_setTLData, 0, 0, 1)
+	ZEND_ARG_INFO(0, tldata)
+ZEND_END_ARG_INFO()
+
+static zend_function_entry krb5_kadm5_principal_functions[] = {
+	PHP_ME(KADM5Principal, __construct,             arginfo_KADM5Principal__construct,  \
ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) +	PHP_ME(KADM5Principal, load,                    \
arginfo_KADM5Principal_none,           ZEND_ACC_PUBLIC) +	PHP_ME(KADM5Principal, \
save,                    arginfo_KADM5Principal_none,           ZEND_ACC_PUBLIC) \
+	PHP_ME(KADM5Principal, delete,                  arginfo_KADM5Principal_none,        \
ZEND_ACC_PUBLIC) +	PHP_ME(KADM5Principal, rename,                  \
arginfo_KADM5Principal_rename,         ZEND_ACC_PUBLIC) +	PHP_ME(KADM5Principal, \
changePassword,          arginfo_KADM5Principal_changePassword, ZEND_ACC_PUBLIC) \
+	PHP_ME(KADM5Principal, getPropertyArray,        arginfo_KADM5Principal_none,        \
ZEND_ACC_PUBLIC) +	PHP_ME(KADM5Principal, getName,                 \
arginfo_KADM5Principal_none,           ZEND_ACC_PUBLIC) +	PHP_ME(KADM5Principal, \
getExpiryTime,           arginfo_KADM5Principal_none,           ZEND_ACC_PUBLIC) \
+	PHP_ME(KADM5Principal, setExpiryTime,           arginfo_KADM5Principal_time,        \
ZEND_ACC_PUBLIC) +	PHP_ME(KADM5Principal, getLastPasswordChange,   \
arginfo_KADM5Principal_none,           ZEND_ACC_PUBLIC) +	PHP_ME(KADM5Principal, \
getPasswordExpiryTime,   arginfo_KADM5Principal_none,           ZEND_ACC_PUBLIC) \
+	PHP_ME(KADM5Principal, setPasswordExpiryTime,   arginfo_KADM5Principal_time,        \
ZEND_ACC_PUBLIC) +	PHP_ME(KADM5Principal, getMaxTicketLifetime,    \
arginfo_KADM5Principal_none,           ZEND_ACC_PUBLIC) +	PHP_ME(KADM5Principal, \
setMaxTicketLifetime,    arginfo_KADM5Principal_time,           ZEND_ACC_PUBLIC) \
+	PHP_ME(KADM5Principal, getMaxRenewableLifetime, arginfo_KADM5Principal_none,        \
ZEND_ACC_PUBLIC) +	PHP_ME(KADM5Principal, setMaxRenewableLifetime, \
arginfo_KADM5Principal_time,           ZEND_ACC_PUBLIC) +	PHP_ME(KADM5Principal, \
getLastModifier,         arginfo_KADM5Principal_none,           ZEND_ACC_PUBLIC) \
+	PHP_ME(KADM5Principal, getLastModificationDate, arginfo_KADM5Principal_none,        \
ZEND_ACC_PUBLIC) +	PHP_ME(KADM5Principal, getKeyVNO,               \
arginfo_KADM5Principal_none,           ZEND_ACC_PUBLIC) +	PHP_ME(KADM5Principal, \
setKeyVNO,               arginfo_KADM5Principal_setKeyVNO,      ZEND_ACC_PUBLIC) \
+	PHP_ME(KADM5Principal, getMasterKeyVNO,         arginfo_KADM5Principal_none,        \
ZEND_ACC_PUBLIC) +	PHP_ME(KADM5Principal, setAttributes,           \
arginfo_KADM5Principal_setAttributes,  ZEND_ACC_PUBLIC) +	PHP_ME(KADM5Principal, \
getAttributes,           arginfo_KADM5Principal_none,           ZEND_ACC_PUBLIC) \
+	PHP_ME(KADM5Principal, getAuxAttributes,        arginfo_KADM5Principal_none,        \
ZEND_ACC_PUBLIC) +	PHP_ME(KADM5Principal, getPolicy,               \
arginfo_KADM5Principal_none,           ZEND_ACC_PUBLIC) +	PHP_ME(KADM5Principal, \
setPolicy,               arginfo_KADM5Principal_setPolicy,      ZEND_ACC_PUBLIC) \
+	PHP_ME(KADM5Principal, clearPolicy,             arginfo_KADM5Principal_none,        \
ZEND_ACC_PUBLIC) +	PHP_ME(KADM5Principal, getLastSuccess,          \
arginfo_KADM5Principal_none,           ZEND_ACC_PUBLIC) +	PHP_ME(KADM5Principal, \
getLastFailed,           arginfo_KADM5Principal_none,           ZEND_ACC_PUBLIC) \
+	PHP_ME(KADM5Principal, getFailedAuthCount,      arginfo_KADM5Principal_none,        \
ZEND_ACC_PUBLIC) +	PHP_ME(KADM5Principal, resetFailedAuthCount,    \
arginfo_KADM5Principal_none,           ZEND_ACC_PUBLIC) +	PHP_ME(KADM5Principal, \
setTLData,               arginfo_KADM5Principal_setTLData,      ZEND_ACC_PUBLIC) \
+	PHP_ME(KADM5Principal, getTLData,               arginfo_KADM5Principal_none,        \
ZEND_ACC_PUBLIC) +	PHP_FE_END
+};
+
+zend_object_handlers krb5_kadm5_principal_handlers;
+
+/* KADM5Principal ctor/dtor */
+#if PHP_MAJOR_VERSION < 7
+static void php_krb5_kadm5_principal_object_dtor(void *obj, zend_object_handle \
handle TSRMLS_DC) +{
+	krb5_kadm5_principal_object *object = (krb5_kadm5_principal_object*)obj;
+
+	krb5_kadm5_object *conn = object->conn;
+	if(conn) {
+		kadm5_free_principal_ent(conn->handle, &object->data);
+	}
+
+	zend_object_std_dtor(&(object->std) TSRMLS_CC);
+	efree(object);
+}
+#else
+static void php_krb5_kadm5_principal_object_free(zend_object *obj TSRMLS_DC)
+{
+	krb5_kadm5_principal_object *object = (krb5_kadm5_principal_object*)((char *)obj - \
XtOffsetOf(krb5_kadm5_principal_object, std)); +	krb5_kadm5_object *conn = \
object->conn; +	if(conn) {
+		kadm5_free_principal_ent(conn->handle, &object->data);
+
+	}
+	zend_object_std_dtor(obj);
+}
+#endif
+
+int php_krb5_register_kadm5_principal(TSRMLS_D) {
+	zend_class_entry kadm5_principal;
+	INIT_CLASS_ENTRY(kadm5_principal, "KADM5Principal", \
krb5_kadm5_principal_functions); +	krb5_ce_kadm5_principal = \
zend_register_internal_class(&kadm5_principal TSRMLS_CC); \
+	krb5_ce_kadm5_principal->create_object = php_krb5_kadm5_principal_object_new; \
+	memcpy(&krb5_kadm5_principal_handlers, zend_get_std_object_handlers(), \
sizeof(zend_object_handlers)); +#if PHP_MAJOR_VERSION >= 7
+	krb5_kadm5_principal_handlers.offset = XtOffsetOf(krb5_kadm5_principal_object, \
std); +	krb5_kadm5_principal_handlers.free_obj = \
php_krb5_kadm5_principal_object_free; +#endif
+	return SUCCESS;
+}
+
+#if PHP_MAJOR_VERSION < 7
+zend_object_value php_krb5_kadm5_principal_object_new(zend_class_entry *ce \
TSRMLS_DC) +{
+	zend_object_value retval;
+	krb5_kadm5_principal_object *object;
+	extern zend_object_handlers krb5_kadm5_principal_handlers;
+
+	object = emalloc(sizeof(krb5_kadm5_principal_object));
+
+	memset(&object->data, 0, sizeof(kadm5_principal_ent_rec));
+	object->loaded = FALSE;
+	object->update_mask = 0;
+	object->conn = NULL;
+
+	zend_object_std_init(&(object->std), ce TSRMLS_CC);
+
+#if PHP_VERSION_ID < 50399
+	zend_hash_copy(object->std.properties, &ce->default_properties,
+					(copy_ctor_func_t) zval_add_ref, NULL,
+					sizeof(zval*));
+#else
+	object_properties_init(&(object->std), ce);
+#endif
+
+	retval.handle = zend_objects_store_put(object, \
php_krb5_kadm5_principal_object_dtor, NULL, NULL TSRMLS_CC); +	retval.handlers = \
&krb5_kadm5_principal_handlers; +	return retval;
+}
+#else
+zend_object* php_krb5_kadm5_principal_object_new(zend_class_entry *ce TSRMLS_DC) {
+	krb5_kadm5_principal_object *object = ecalloc(1, \
sizeof(krb5_kadm5_principal_object) + zend_object_properties_size(ce)); \
+	zend_object_std_init(&object->std, ce TSRMLS_CC); \
+	object_properties_init(&object->std, ce); +	object->std.handlers = \
&krb5_kadm5_principal_handlers; +	return &object->std;
+}
+#endif
+
+/* {{{ proto KADM5Principal KADM5Principal::__construct(string $principal [, KADM5 \
$connection [, boolean $noload] ]) + */
+PHP_METHOD(KADM5Principal, __construct)
+{
+
+	krb5_kadm5_principal_object *this = KRB5_THIS_KADM_PRINCIPAL;
+	char *sprinc = NULL;
+	strsize_t sprinc_len;
+
+	zend_bool noload = FALSE;
+	zval *obj = NULL;
+
+
+	KRB5_SET_ERROR_HANDLING(EH_THROW);
+	if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|Ob", &sprinc, &sprinc_len, \
&obj, krb5_ce_kadm5, &noload) == FAILURE) { +		RETURN_NULL();
+	}
+	KRB5_SET_ERROR_HANDLING(EH_NORMAL);
+
+	zend_update_property_string(krb5_ce_kadm5_principal, getThis(), "princname", \
sizeof("princname"), sprinc TSRMLS_CC); +
+	if(obj && Z_TYPE_P(obj) == IS_OBJECT) {
+		zend_update_property(krb5_ce_kadm5_principal, getThis(), "connection", \
sizeof("connection"), obj TSRMLS_CC); +		this->conn = KRB5_KADM(obj);
+
+		if ( noload != TRUE ) {
+#if PHP_MAJOR_VERSION < 7
+			zval *dummy_retval, *func;
+			MAKE_STD_ZVAL(func);
+			ZVAL_STRING(func, "load", 1);
+			MAKE_STD_ZVAL(dummy_retval);
+			if(call_user_function(&krb5_ce_kadm5_principal->function_table,
+									&getThis(), func, dummy_retval, 0,
+									NULL TSRMLS_CC) == FAILURE) {
+				zval_ptr_dtor(&func);
+				zval_ptr_dtor(&dummy_retval);
+				zend_throw_exception(NULL, "Failed to update KADM5Principal object", 0 \
TSRMLS_CC); +				return;
+			}
+
+			zval_ptr_dtor(&func);
+			zval_ptr_dtor(&dummy_retval);
+#else
+			zval func;
+			zval dummy_retval;
+			ZVAL_STRING(&func, "load");
+			if(call_user_function(&krb5_ce_kadm5_policy->function_table, getThis(), &func, \
&dummy_retval, 0, +									NULL TSRMLS_CC) == FAILURE) {
+				zval_dtor(&func);
+				zval_dtor(&dummy_retval);
+				zend_throw_exception(NULL, "Failed to update KADM5Policy object", 0 TSRMLS_CC);
+				return;
+			}
+			zval_dtor(&func);
+			zval_dtor(&dummy_retval);
+#endif
+		}
+	}
+}
+/* }}} */
+
+
+#if PHP_MAJOR_VERSION < 7
+#define KRB5_KADM_PRINCIPAL_GET_CONNECTION \
zend_read_property(krb5_ce_kadm5_principal, getThis(), "connection", \
sizeof("connection"),1 TSRMLS_CC) +#else
+#define KRB5_KADM_PRINCIPAL_GET_CONNECTION \
zend_read_property(krb5_ce_kadm5_principal, getThis(), "connection", \
sizeof("connection"),1, NULL TSRMLS_CC) +#endif
+
+#if PHP_MAJOR_VERSION < 7
+#define KRB5_KADM_PRINCIPAL_GET_PRINCNAME \
zend_read_property(krb5_ce_kadm5_principal, getThis(), "princname", \
sizeof("princname"),1 TSRMLS_CC) +#else
+#define KRB5_KADM_PRINCIPAL_GET_PRINCNAME \
zend_read_property(krb5_ce_kadm5_principal, getThis(), "princname", \
sizeof("princname"),1, NULL TSRMLS_CC) +#endif
+
+/* {{{ proto KADM5Principal KADM5Principal::load()
+ */
+PHP_METHOD(KADM5Principal, load)
+{
+	kadm5_ret_t retval;
+	krb5_kadm5_principal_object *obj = KRB5_THIS_KADM_PRINCIPAL;
+	krb5_kadm5_object *kadm5;
+	zval *connobj = NULL;
+	zval *princname = NULL;
+
+	if (zend_parse_parameters_none() == FAILURE) {
+		return;
+	}
+
+	connobj = KRB5_KADM_PRINCIPAL_GET_CONNECTION;
+	princname = KRB5_KADM_PRINCIPAL_GET_PRINCNAME;
+
+	if ( Z_ISNULL_P(connobj)) {
+		zend_throw_exception(NULL, "No valid connection available", 0 TSRMLS_CC);
+		return;
+	}
+
+	kadm5 = KRB5_KADM(connobj);
+	if(!kadm5) {
+		zend_throw_exception(NULL, "No valid connection available", 0 TSRMLS_CC);
+		return;
+	}
+
+	if ( obj->data.principal ) {
+		krb5_free_principal(kadm5->ctx, obj->data.principal);
+		obj->data.principal = NULL;
+	}
+
+	zend_string *pnstr = zval_get_string(princname TSRMLS_CC);
+	fprintf(stderr, "Loading %s\n", pnstr->val);
+	if(krb5_parse_name(kadm5->ctx, pnstr->val, &obj->data.principal)) {
+		zend_string_release(pnstr);
+		zend_throw_exception(NULL, "Failed to parse principal name", 0 TSRMLS_CC);
+		return;
+	}
+	zend_string_release(pnstr);
+
+	retval = kadm5_get_principal(kadm5->handle, obj->data.principal, &obj->data, \
KADM5_PRINCIPAL_NORMAL_MASK | KADM5_TL_DATA); +	if(retval != KADM5_OK) {
+		krb5_free_principal(kadm5->ctx, obj->data.principal);
+		obj->data.principal = NULL;
+		const char* errmsg = krb5_get_error_message(kadm5->ctx, (int)retval);
+		zend_throw_exception(NULL, errmsg, (int)retval TSRMLS_CC);
+		krb5_free_error_message(kadm5->ctx, errmsg);
+		return;
+	}
+
+	obj->loaded = TRUE;
+	obj->update_mask = 0;
+	RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto KADM5Principal KADM5Principal::save()
+ */
+PHP_METHOD(KADM5Principal, save)
+{
+	kadm5_ret_t retval;
+	krb5_kadm5_principal_object *obj = KRB5_THIS_KADM_PRINCIPAL;
+
+	krb5_kadm5_object *kadm5;
+	zval *connobj = NULL;
+
+	if (zend_parse_parameters_none() == FAILURE) {
+		return;
+	}
+
+
+	connobj = KRB5_KADM_PRINCIPAL_GET_CONNECTION;
+	if ( Z_ISNULL_P(connobj)) {
+		zend_throw_exception(NULL, "No valid connection available", 0 TSRMLS_CC);
+		return;
+	}
+
+	kadm5 = KRB5_KADM(connobj);
+	if(!kadm5) {
+		zend_throw_exception(NULL, "No valid connection available", 0 TSRMLS_CC);
+		return;
+	}
+
+	if(obj->update_mask == 0) {
+		RETURN_TRUE;
+	}
+
+	retval = kadm5_modify_principal(kadm5->handle, &obj->data, obj->update_mask);
+	if(retval != KADM5_OK) {
+		const char* errmsg = krb5_get_error_message(kadm5->ctx, (int)retval);
+		zend_throw_exception(NULL, errmsg, (int)retval TSRMLS_CC);
+		krb5_free_error_message(kadm5->ctx, errmsg);
+		return;
+	}
+
+	obj->update_mask = 0;
+
+	RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto KADM5Principal KADM5Principal::changePassword(string $password)
+ */
+PHP_METHOD(KADM5Principal, changePassword)
+{
+	kadm5_ret_t retval;
+	krb5_kadm5_object *kadm5 = NULL;
+	zval *connobj = NULL;
+	zval *princname = NULL;
+
+	char *newpass = NULL;
+	strsize_t newpass_len;
+
+	krb5_principal princ;
+
+	if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &newpass, &newpass_len) == \
FAILURE) { +		RETURN_FALSE;
+	}
+
+	connobj = KRB5_KADM_PRINCIPAL_GET_CONNECTION;
+	princname = KRB5_KADM_PRINCIPAL_GET_PRINCNAME;
+
+
+	if ( Z_ISNULL_P(connobj) ) {
+		zend_throw_exception(NULL, "No valid connection available", 0 TSRMLS_CC);
+		return;
+	}
+
+	kadm5 = KRB5_KADM(connobj);
+	if(!kadm5) {
+		zend_throw_exception(NULL, "No valid connection available", 0 TSRMLS_CC);
+		return;
+	}
+
+   	zend_string *pnstr = zval_get_string(princname TSRMLS_CC);
+	if(krb5_parse_name(kadm5->ctx, pnstr->val, &princ)) {
+		zend_string_release(pnstr);
+		zend_throw_exception(NULL, "Failed to parse principal name", 0 TSRMLS_CC);
+		return;
+	}
+	zend_string_release(pnstr);
+
+	retval = kadm5_chpass_principal(kadm5->handle, princ, newpass);
+	krb5_free_principal(kadm5->ctx, princ);
+
+	if(retval != KADM5_OK) {
+		const char* errmsg = krb5_get_error_message(kadm5->ctx, (int)retval);
+		zend_throw_exception(NULL, errmsg, (int)retval TSRMLS_CC);
+		krb5_free_error_message(kadm5->ctx, errmsg);
+		return;
+	}
+
+	RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto KADM5Principal KADM5Principal::delete()
+ */
+PHP_METHOD(KADM5Principal, delete)
+{
+	kadm5_ret_t retval;
+	krb5_kadm5_principal_object *obj = KRB5_THIS_KADM_PRINCIPAL;
+
+	krb5_kadm5_object *kadm5;
+	zval *connobj = NULL;
+
+	if (zend_parse_parameters_none() == FAILURE) {
+		return;
+	}
+
+	if ( ! obj->loaded ) {
+		zend_throw_exception(NULL, "Object is not loaded", 0 TSRMLS_CC);
+		return;
+	}
+
+	connobj = KRB5_KADM_PRINCIPAL_GET_CONNECTION;
+	if ( Z_ISNULL_P(connobj) ) {
+		zend_throw_exception(NULL, "No valid connection available", 0 TSRMLS_CC);
+		return;
+	}
+
+	kadm5 = KRB5_KADM(connobj);
+	if(!kadm5) {
+		zend_throw_exception(NULL, "No valid connection available", 0 TSRMLS_CC);
+		return;
+	}
+
+
+	retval = kadm5_delete_principal(kadm5->handle, obj->data.principal);
+	if(retval != KADM5_OK) {
+		const char* errmsg = krb5_get_error_message(kadm5->ctx, (int)retval);
+		zend_throw_exception(NULL, errmsg, (int)retval TSRMLS_CC);
+		krb5_free_error_message(kadm5->ctx, errmsg);
+		return;
+	}
+	obj->loaded = FALSE;
+
+	RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto KADM5Principal KADM5Principal::rename(string $dst_name [, string \
$dst_pw ]) + */
+PHP_METHOD(KADM5Principal, rename)
+{
+	kadm5_ret_t retval;
+	krb5_kadm5_principal_object *obj = KRB5_THIS_KADM_PRINCIPAL;
+	krb5_kadm5_object *kadm5;
+	zval *connobj = NULL;
+	char *dst_name = NULL, *dst_pw = NULL;
+	strsize_t dst_name_len, dst_pw_len;
+	krb5_principal dst_princ;
+
+	if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &dst_name, \
&dst_name_len, +								&dst_pw, &dst_pw_len) == FAILURE) {
+		RETURN_FALSE;
+	}
+
+	if ( ! obj->loaded ) {
+		zend_throw_exception(NULL, "Object is not loaded", 0 TSRMLS_CC);
+		return;
+	}
+
+	connobj = KRB5_KADM_PRINCIPAL_GET_CONNECTION;
+	if ( Z_ISNULL_P(connobj)) {
+		zend_throw_exception(NULL, "No valid connection available", 0 TSRMLS_CC);
+		return;
+	}
+	kadm5 = KRB5_KADM(connobj);
+	if(!kadm5) {
+		zend_throw_exception(NULL, "No valid connection available", 0 TSRMLS_CC);
+		return;
+	}
+
+
+	krb5_parse_name(kadm5->ctx, dst_name, &dst_princ);
+	retval = kadm5_rename_principal(kadm5->handle, obj->data.principal, dst_princ);
+	if(retval != KADM5_OK) {
+		krb5_free_principal(kadm5->ctx, dst_princ);
+		const char* errmsg = krb5_get_error_message(kadm5->ctx, (int)retval);
+		zend_throw_exception(NULL, errmsg, (int)retval TSRMLS_CC);
+		krb5_free_error_message(kadm5->ctx, errmsg);
+		return;
+	}
+
+	if(dst_pw) {
+		retval = kadm5_chpass_principal(kadm5->handle, dst_princ, dst_pw);
+		if(retval != KADM5_OK) {
+			krb5_free_principal(kadm5->ctx, dst_princ);
+			const char* errmsg = krb5_get_error_message(kadm5->ctx, (int)retval);
+			zend_throw_exception(NULL, errmsg, (int)retval TSRMLS_CC);
+			krb5_free_error_message(kadm5->ctx, errmsg);
+			return;
+		}
+	}
+
+	retval = kadm5_get_principal(kadm5->handle, dst_princ, &obj->data, \
KADM5_PRINCIPAL_NORMAL_MASK); +	if(retval != KADM5_OK) {
+		krb5_free_principal(kadm5->ctx, dst_princ);
+		const char* errmsg = krb5_get_error_message(kadm5->ctx, (int)retval);
+		zend_throw_exception(NULL, errmsg, (int)retval TSRMLS_CC);
+		krb5_free_error_message(kadm5->ctx, errmsg);
+		return;
+	}
+
+	krb5_free_principal(kadm5->ctx, dst_princ);
+}
+/* }}} */
+
+/** property accessors **/
+
+/* {{{ proto array KADM5Principal::getPropertyArray()
+ */
+PHP_METHOD(KADM5Principal, getPropertyArray)
+{
+	krb5_kadm5_principal_object *obj = KRB5_THIS_KADM_PRINCIPAL;
+
+	krb5_kadm5_object *kadm5;
+	zval *connobj = NULL;
+	connobj = KRB5_KADM_PRINCIPAL_GET_CONNECTION;
+
+	if (zend_parse_parameters_none() == FAILURE) {
+		return;
+	}
+
+
+	kadm5 = KRB5_KADM(connobj);
+	if(!kadm5) {
+		zend_throw_exception(NULL, "No valid connection available", 0 TSRMLS_CC);
+		return;
+	}
+
+	array_init(return_value);
+
+	char *tstring;
+	if ( obj->data.principal != NULL ) {
+		krb5_unparse_name(kadm5->ctx, obj->data.principal, &tstring);
+		_add_assoc_string(return_value, "princname", tstring);
+		krb5_free_unparsed_name(kadm5->ctx, tstring);
+	} else {
+		zend_string *val = zval_get_string(KRB5_KADM_PRINCIPAL_GET_PRINCNAME TSRMLS_CC);
+		_add_assoc_string(return_value, "princname", val->val);
+		zend_string_release(val);
+	}
+
+
+
+	add_assoc_long(return_value, "princ_expire_time", obj->data.princ_expire_time);
+	add_assoc_long(return_value, "last_pwd_change", obj->data.last_pwd_change);
+	add_assoc_long(return_value, "pw_expiration", obj->data.pw_expiration);
+	add_assoc_long(return_value, "max_life", obj->data.max_life);
+
+	if ( obj->data.mod_name ) {
+		krb5_unparse_name(kadm5->ctx, obj->data.mod_name, &tstring);
+		_add_assoc_string(return_value, "mod_name", tstring);
+		krb5_free_unparsed_name(kadm5->ctx, tstring);
+	}
+
+	add_assoc_long(return_value, "mod_date", obj->data.mod_date);
+	add_assoc_long(return_value, "attributes", obj->data.attributes);
+	add_assoc_long(return_value, "kvno", obj->data.kvno);
+	add_assoc_long(return_value, "mkvno", obj->data.mkvno);
+	if(obj->data.policy) _add_assoc_string(return_value, "policy", obj->data.policy);
+	add_assoc_long(return_value, "aux_attributes", obj->data.aux_attributes);
+	add_assoc_long(return_value, "max_renewable_life", obj->data.max_renewable_life);
+	add_assoc_long(return_value, "last_success", obj->data.last_success);
+	add_assoc_long(return_value, "last_failed", obj->data.last_failed);
+	add_assoc_long(return_value, "fail_auth_count", obj->data.fail_auth_count);
+
+	if ( obj->data.n_tl_data  > 0 ) {
+		zval *tldata = ecalloc(1, sizeof(zval));
+		_ALLOC_INIT_ZVAL(tldata);
+		array_init(tldata);
+		php_krb5_kadm5_tldata_to_array(tldata, obj->data.tl_data, obj->data.n_tl_data \
TSRMLS_CC); +		add_assoc_zval(return_value, "tldata", tldata);
+		//zval_ptr_dtor(tldata);
+	}
+}
+/* }}} */
+
+/* {{{ proto KADM5Principal KADM5Principal::getName()
+ */
+PHP_METHOD(KADM5Principal, getName)
+{
+	krb5_kadm5_principal_object *obj = KRB5_THIS_KADM_PRINCIPAL;
+
+	if (zend_parse_parameters_none() == FAILURE) {
+		return;
+	}
+	if(obj->loaded) {
+		char *princname;
+		krb5_kadm5_object *kadm5;
+		zval *connobj = NULL;
+
+		connobj = KRB5_KADM_PRINCIPAL_GET_CONNECTION;
+		if ( Z_ISNULL_P(connobj)) {
+			zend_throw_exception(NULL, "No valid connection available", 0 TSRMLS_CC);
+			return;
+		}
+		kadm5 = KRB5_KADM(connobj);
+		if ( !kadm5 ) {
+			zend_throw_exception(NULL, "No valid connection available", 0 TSRMLS_CC);
+			return;
+		}
+
+		krb5_unparse_name(kadm5->ctx,obj->data.principal,&princname);
+		_RETVAL_STRING(princname);
+		krb5_free_unparsed_name(kadm5->ctx, princname);
+	} else {
+		zend_string *val = zval_get_string(KRB5_KADM_PRINCIPAL_GET_PRINCNAME TSRMLS_CC);
+		_RETVAL_STRING(val->val);
+		zend_string_release(val);
+	}
+}
+/* }}} */
+
+/* {{{ proto KADM5Principal KADM5Principal::getExpiryTime()
+ */
+PHP_METHOD(KADM5Principal, getExpiryTime)
+{
+	krb5_kadm5_principal_object *obj = KRB5_THIS_KADM_PRINCIPAL;
+
+	if (zend_parse_parameters_none() == FAILURE) {
+		return;
+	}
+
+	RETURN_LONG(obj->data.princ_expire_time);
+}
+/* }}} */
+
+/* {{{ proto KADM5Principal KADM5Principal::setExpiryTime(int $expiry_time)
+ */
+PHP_METHOD(KADM5Principal, setExpiryTime)
+{
+	krb5_kadm5_principal_object *obj = KRB5_THIS_KADM_PRINCIPAL;
+	zend_long expiry_time;
+
+	if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &expiry_time) == FAILURE) \
{ +		RETURN_FALSE;
+	}
+
+	obj->data.princ_expire_time = expiry_time;
+	obj->update_mask |= KADM5_PRINC_EXPIRE_TIME;
+
+	RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto KADM5Principal KADM5Principal::getLastPasswordChange()
+ */
+PHP_METHOD(KADM5Principal, getLastPasswordChange)
+{
+	krb5_kadm5_principal_object *obj = KRB5_THIS_KADM_PRINCIPAL;
+
+	if (zend_parse_parameters_none() == FAILURE) {
+		return;
+	}
+	RETURN_LONG(obj->data.last_pwd_change);
+}
+/* }}} */
+
+/* {{{ proto KADM5Principal KADM5Principal::getPasswordExpiryTime()
+ */
+PHP_METHOD(KADM5Principal, getPasswordExpiryTime)
+{
+	krb5_kadm5_principal_object *obj = KRB5_THIS_KADM_PRINCIPAL;
+
+	if (zend_parse_parameters_none() == FAILURE) {
+		return;
+	}
+	RETURN_LONG(obj->data.pw_expiration);
+}
+/* }}} */
+
+/* {{{ proto KADM5Principal KADM5Principal::setPasswordExpiryTime(int \
$pwd_expiry_time) + */
+PHP_METHOD(KADM5Principal, setPasswordExpiryTime)
+{
+	krb5_kadm5_principal_object *obj = KRB5_THIS_KADM_PRINCIPAL;
+	zend_long pwd_expiry_time;
+
+	if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &pwd_expiry_time) == \
FAILURE) { +		RETURN_FALSE;
+	}
+
+	obj->data.pw_expiration = pwd_expiry_time;
+	obj->update_mask |= KADM5_PW_EXPIRATION;
+
+	RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto KADM5Principal KADM5Principal::getMaxTicketLifetime()
+ */
+PHP_METHOD(KADM5Principal, getMaxTicketLifetime)
+{
+	krb5_kadm5_principal_object *obj = KRB5_THIS_KADM_PRINCIPAL;
+
+	if (zend_parse_parameters_none() == FAILURE) {
+		return;
+	}
+	RETURN_LONG(obj->data.max_life);
+}
+/* }}} */
+
+/* {{{ proto KADM5Principal KADM5Principal::setMaxTicketLifetime(int $max_lifetime)
+ */
+PHP_METHOD(KADM5Principal, setMaxTicketLifetime)
+{
+	krb5_kadm5_principal_object *obj = KRB5_THIS_KADM_PRINCIPAL;
+	zend_long max_lifetime;
+
+	if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &max_lifetime) == FAILURE) \
{ +		RETURN_FALSE;
+	}
+
+	obj->data.max_life = max_lifetime;
+	obj->update_mask |= KADM5_MAX_LIFE;
+
+	RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto KADM5Principal KADM5Principal::getMaxRenewableLifetime()
+ */
+PHP_METHOD(KADM5Principal, getMaxRenewableLifetime)
+{
+	krb5_kadm5_principal_object *obj = KRB5_THIS_KADM_PRINCIPAL;
+
+	if (zend_parse_parameters_none() == FAILURE) {
+		return;
+	}
+	RETURN_LONG(obj->data.max_renewable_life);
+}
+/* }}} */
+
+/* {{{ proto KADM5Principal KADM5Principal::setMaxRenewableLifetime(int \
$max_renewable_lifetime) + */
+PHP_METHOD(KADM5Principal, setMaxRenewableLifetime)
+{
+	krb5_kadm5_principal_object *obj = KRB5_THIS_KADM_PRINCIPAL;
+	zend_long max_renewable_lifetime;
+
+	if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &max_renewable_lifetime) \
== FAILURE) { +		RETURN_FALSE;
+	}
+
+	obj->data.max_renewable_life = max_renewable_lifetime;
+	obj->update_mask |= KADM5_MAX_RLIFE;
+
+	RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto KADM5Principal KADM5Principal::getLastModifier()
+ */
+PHP_METHOD(KADM5Principal, getLastModifier)
+{
+	char *princname;
+	krb5_kadm5_principal_object *obj = KRB5_THIS_KADM_PRINCIPAL;
+	krb5_kadm5_object *kadm5;
+	zval *connobj = NULL;
+
+	if (zend_parse_parameters_none() == FAILURE) {
+		return;
+	}
+
+
+	if(obj->loaded) {
+		connobj = KRB5_KADM_PRINCIPAL_GET_CONNECTION;
+		if ( Z_ISNULL_P(connobj)) {
+			zend_throw_exception(NULL, "No valid connection available", 0 TSRMLS_CC);
+			return;
+		}
+		kadm5 = KRB5_KADM(connobj);
+		if ( !kadm5 ) {
+			zend_throw_exception(NULL, "No valid connection available", 0 TSRMLS_CC);
+			return;
+		}
+
+		krb5_unparse_name(kadm5->ctx,obj->data.mod_name,&princname);
+		_RETVAL_STRING(princname);
+		krb5_free_unparsed_name(kadm5->ctx, princname);
+		return;
+	} else {
+		RETURN_NULL();
+	}
+}
+/* }}} */
+
+/* {{{ proto KADM5Principal KADM5Principal::getLastModificationDate()
+ */
+PHP_METHOD(KADM5Principal, getLastModificationDate)
+{
+	krb5_kadm5_principal_object *obj = KRB5_THIS_KADM_PRINCIPAL;
+
+	if (zend_parse_parameters_none() == FAILURE) {
+		return;
+	}
+	RETURN_LONG(obj->data.mod_date);
+}
+/* }}} */
+
+/* {{{ proto KADM5Principal KADM5Principal::getKeyVNO()
+ */
+PHP_METHOD(KADM5Principal, getKeyVNO)
+{
+	krb5_kadm5_principal_object *obj = KRB5_THIS_KADM_PRINCIPAL;
+
+	if (zend_parse_parameters_none() == FAILURE) {
+		return;
+	}
+	RETURN_LONG(obj->data.kvno);
+}
+/* }}} */
+
+/* {{{ proto KADM5Principal KADM5Principal::setKeyVNO(int $kvno)
+ */
+PHP_METHOD(KADM5Principal, setKeyVNO)
+{
+	krb5_kadm5_principal_object *obj = KRB5_THIS_KADM_PRINCIPAL;
+	zend_long kvno;
+
+	if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &kvno) == FAILURE) {
+		RETURN_FALSE;
+	}
+
+	obj->data.kvno = kvno;
+	obj->update_mask |= KADM5_KVNO;
+
+	RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto KADM5Principal KADM5Principal::getMasterKeyVNO()
+ */
+PHP_METHOD(KADM5Principal, getMasterKeyVNO)
+{
+	krb5_kadm5_principal_object *obj = KRB5_THIS_KADM_PRINCIPAL;
+
+	if (zend_parse_parameters_none() == FAILURE) {
+		return;
+	}
+	RETURN_LONG(obj->data.mkvno);
+}
+/* }}} */
+
+/* {{{ proto KADM5Principal KADM5Principal::setAttributes(int $attrs)
+ */
+PHP_METHOD(KADM5Principal, setAttributes)
+{
+	krb5_kadm5_principal_object *obj = KRB5_THIS_KADM_PRINCIPAL;
+	zend_long attrs;
+
+	if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &attrs) == FAILURE) {
+		RETURN_FALSE;
+	}
+
+	obj->data.attributes = attrs;
+	obj->update_mask |= KADM5_ATTRIBUTES;
+
+	RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto KADM5Principal KADM5Principal::getAttributes()
+ */
+PHP_METHOD(KADM5Principal, getAttributes)
+{
+	krb5_kadm5_principal_object *obj = KRB5_THIS_KADM_PRINCIPAL;
+
+	if (zend_parse_parameters_none() == FAILURE) {
+		return;
+	}
+	RETURN_LONG(obj->data.attributes);
+}
+/* }}} */
+
+/* {{{ proto KADM5Principal KADM5Principal::getAuxAttributes()
+ */
+PHP_METHOD(KADM5Principal, getAuxAttributes)
+{
+	krb5_kadm5_principal_object *obj = KRB5_THIS_KADM_PRINCIPAL;
+
+	if (zend_parse_parameters_none() == FAILURE) {
+		return;
+	}
+	RETURN_LONG(obj->data.aux_attributes);
+}
+/* }}} */
+
+/* {{{ proto KADM5Principal KADM5Principal::getPolicy()
+ */
+PHP_METHOD(KADM5Principal, getPolicy)
+{
+	krb5_kadm5_principal_object *obj = KRB5_THIS_KADM_PRINCIPAL;
+	zval *connobj = NULL;
+
+	if (zend_parse_parameters_none() == FAILURE) {
+		return;
+	}
+	if(obj->data.policy) {
+
+		connobj = KRB5_KADM_PRINCIPAL_GET_CONNECTION;
+		if ( Z_ISNULL_P(connobj)) {
+			zend_throw_exception(NULL, "No valid connection available", 0 TSRMLS_CC);
+			return;
+		}
+
+#if PHP_MAJOR_VERSION < 7
+		zval *func;
+		zval *args[1];
+		MAKE_STD_ZVAL(func);
+		ZVAL_STRING(func, "getPolicy", 1);
+		MAKE_STD_ZVAL(args[0]);
+		ZVAL_STRING(args[0], obj->data.policy, 1);
+
+		if(call_user_function(&krb5_ce_kadm5_policy->function_table,
+								&connobj, func, return_value, 1,
+								args TSRMLS_CC) == FAILURE) {
+			zval_ptr_dtor(&args[0]);
+			zval_ptr_dtor(&func);
+			zend_throw_exception(NULL, "Failed to instantiate KADM5Policy object", 0 \
TSRMLS_CC); +			return;
+		}
+
+		zval_ptr_dtor(&args[0]);
+		zval_ptr_dtor(&func);
+#else
+		zval func;
+		zval args[1];
+		ZVAL_STRING(&func, "getPolicy");
+		ZVAL_STRING(&args[0], obj->data.policy);
+		if(call_user_function(&krb5_ce_kadm5_policy->function_table, connobj, &func, \
return_value, 1, +								args TSRMLS_CC) == FAILURE) {
+			zval_dtor(&args[0]);
+			zval_dtor(&func);
+			zend_throw_exception(NULL, "Failed to instantiate KADM5Policy object", 0 \
TSRMLS_CC); +			return;
+		}
+		zval_dtor(&args[0]);
+		zval_dtor(&func);
+#endif
+	}
+}
+/* }}} */
+
+/* {{{ proto KADM5Principal KADM5Principal::setPolicy(mixed $policy)
+ */
+PHP_METHOD(KADM5Principal, setPolicy)
+{
+	krb5_kadm5_principal_object *obj = KRB5_THIS_KADM_PRINCIPAL;
+	zval *policy = NULL;
+	krb5_kadm5_policy_object *pol;
+	zend_string *pstr;
+
+	if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z", &policy) == FAILURE) {
+		RETURN_FALSE;
+	}
+
+	if(obj->data.policy) {
+		free(obj->data.policy);
+		obj->data.policy = NULL;
+	}
+
+	switch(Z_TYPE_P(policy)) {
+
+		case IS_NULL:
+			if(obj->data.policy) {
+				obj->data.policy = NULL;
+				obj->update_mask |= KADM5_POLICY_CLR;
+			}
+			break;
+
+		case IS_OBJECT:
+			if(Z_OBJCE_P(policy) == krb5_ce_kadm5_policy) {
+				pol = KRB5_KADM_POLICY(policy);
+
+				obj->data.policy = strdup(pol->policy);
+				obj->update_mask |= KADM5_POLICY;
+				break;
+			}
+
+		default:
+			pstr = zval_get_string(policy TSRMLS_CC);
+			obj->data.policy = strdup(pstr->val);
+			obj->update_mask |= KADM5_POLICY;
+			zend_string_release(pstr);
+			break;
+
+	}
+
+	RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto KADM5Principal KADM5Principal::clearPolicy()
+ */
+PHP_METHOD(KADM5Principal, clearPolicy)
+{
+	krb5_kadm5_principal_object *obj = KRB5_THIS_KADM_PRINCIPAL;
+
+	if (zend_parse_parameters_none() == FAILURE) {
+		return;
+	}
+	if ( obj->data.policy ) {
+		free(obj->data.policy);
+	}
+	obj->data.policy = NULL;
+	obj->update_mask |= KADM5_POLICY_CLR;
+
+	RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto KADM5Principal KADM5Principal::getLastSuccess()
+ */
+PHP_METHOD(KADM5Principal, getLastSuccess)
+{
+	krb5_kadm5_principal_object *obj = KRB5_THIS_KADM_PRINCIPAL;
+
+	if (zend_parse_parameters_none() == FAILURE) {
+		return;
+	}
+	RETURN_LONG(obj->data.last_success);
+}
+/* }}} */
+
+/* {{{ proto KADM5Principal KADM5Principal::getLastFailed()
+ */
+PHP_METHOD(KADM5Principal, getLastFailed)
+{
+	krb5_kadm5_principal_object *obj = KRB5_THIS_KADM_PRINCIPAL;
+
+	if (zend_parse_parameters_none() == FAILURE) {
+		return;
+	}
+	RETURN_LONG(obj->data.last_failed);
+}
+/* }}} */
+
+/* {{{ proto KADM5Principal KADM5Principal::getFailedAuthCount()
+ */
+PHP_METHOD(KADM5Principal, getFailedAuthCount)
+{
+	krb5_kadm5_principal_object *obj = KRB5_THIS_KADM_PRINCIPAL;
+
+	if (zend_parse_parameters_none() == FAILURE) {
+		return;
+	}
+	RETURN_LONG(obj->data.fail_auth_count);
+}
+/* }}} */
+
+/* {{{ proto KADM5Principal KADM5Principal::resetFailedAuthCount()
+ */
+PHP_METHOD(KADM5Principal, resetFailedAuthCount)
+{
+	krb5_kadm5_principal_object *obj = KRB5_THIS_KADM_PRINCIPAL;
+
+	if (zend_parse_parameters_none() == FAILURE) {
+		return;
+	}
+	obj->data.fail_auth_count = 0;
+	obj->update_mask |= KADM5_FAIL_AUTH_COUNT;
+}
+/* }}} */
+
+
+/* {{{ proto array KADM5Principal::getTLData()
+ *
+ */
+PHP_METHOD(KADM5Principal, getTLData)
+{
+	krb5_kadm5_principal_object *obj = KRB5_THIS_KADM_PRINCIPAL;
+
+	if (zend_parse_parameters_none() == FAILURE) {
+		return;
+	}
+
+	array_init(return_value);
+	php_krb5_kadm5_tldata_to_array(return_value, obj->data.tl_data, obj->data.n_tl_data \
TSRMLS_CC); +}
+/* }}} */
+
+/* {{{ proto void KADM5Principal::setTLData(array)
+ *
+ */
+PHP_METHOD(KADM5Principal, setTLData)
+{
+	krb5_kadm5_principal_object *obj = KRB5_THIS_KADM_PRINCIPAL;
+	zval *array;
+
+	if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array) == FAILURE) {
+		RETURN_FALSE;
+	}
+
+	if ( obj->data.tl_data && obj->data.n_tl_data > 0 ) {
+		php_krb5_kadm5_tldata_free(obj->data.tl_data, obj->data.n_tl_data TSRMLS_CC);
+	}
+	obj->data.tl_data = php_krb5_kadm5_tldata_from_array(array, &obj->data.n_tl_data \
TSRMLS_CC); +	obj->update_mask |= KADM5_TL_DATA;
+}
+/* }}} */

Copied: pecl/krb5/tags/krb5-1.1.0/trunk/kadm5_tldata.c (from rev 339675, \
pecl/krb5/trunk/kadm5_tldata.c) \
                ===================================================================
--- pecl/krb5/tags/krb5-1.1.0/trunk/kadm5_tldata.c	                        (rev 0)
+++ pecl/krb5/tags/krb5-1.1.0/trunk/kadm5_tldata.c	2016-07-16 14:46:31 UTC (rev \
339676) @@ -0,0 +1,246 @@
+/**
+* Copyright (c) 2016 Moritz Bechler
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+* THE SOFTWARE.
+**/
+
+#include "config.h"
+#include "php_krb5.h"
+#include "php_krb5_kadm.h"
+#include "compat.h"
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_KADM5TLData_none, 0, 0, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_KADM5TLData__construct, 0, 0, 0)
+ZEND_END_ARG_INFO()
+
+static zend_function_entry krb5_kadm5_tldata_functions[] = {
+	PHP_ME(KADM5TLData, __construct, arginfo_KADM5TLData__construct, ZEND_ACC_PUBLIC | \
ZEND_ACC_CTOR) +	PHP_ME(KADM5TLData, getType, arginfo_KADM5TLData_none, \
ZEND_ACC_PUBLIC) +	PHP_ME(KADM5TLData, getData, arginfo_KADM5TLData_none, \
ZEND_ACC_PUBLIC) +};
+
+zend_object_handlers krb5_kadm5_tldata_handlers;
+
+/* KADM5Principal ctor/dtor */
+#if PHP_MAJOR_VERSION < 7
+static void php_krb5_kadm5_tldata_object_dtor(void *obj, zend_object_handle handle \
TSRMLS_DC) +{
+	krb5_kadm5_tldata_object *object = (krb5_kadm5_tldata_object*)obj;
+	zend_object_std_dtor(&(object->std) TSRMLS_CC);
+
+	if(object) {
+		if ( object->data.tl_data_contents ) {
+			efree(object->data.tl_data_contents);
+		}
+		efree(object);
+	}
+}
+#else
+static void php_krb5_kadm5_tldata_object_free(zend_object *obj TSRMLS_DC)
+{
+	krb5_kadm5_tldata_object *object = (krb5_kadm5_tldata_object*)((char *)obj - \
XtOffsetOf(krb5_kadm5_tldata_object, std)); +	if ( object->data.tl_data_contents ) {
+		efree(object->data.tl_data_contents);
+	}
+}
+#endif
+
+int php_krb5_register_kadm5_tldata(TSRMLS_D) {
+
+
+	zend_class_entry kadm5_tldata;
+	INIT_CLASS_ENTRY(kadm5_tldata, "KADM5TLData", krb5_kadm5_tldata_functions);
+	krb5_ce_kadm5_tldata = zend_register_internal_class(&kadm5_tldata TSRMLS_CC);
+	krb5_ce_kadm5_tldata->create_object = php_krb5_kadm5_tldata_object_new;
+	memcpy(&krb5_kadm5_tldata_handlers, zend_get_std_object_handlers(), \
sizeof(zend_object_handlers)); +#if PHP_MAJOR_VERSION >= 7
+	krb5_kadm5_tldata_handlers.offset = XtOffsetOf(krb5_kadm5_tldata_object, std);
+	krb5_kadm5_tldata_handlers.free_obj = php_krb5_kadm5_tldata_object_free;
+#endif
+	return SUCCESS;
+}
+
+
+#if PHP_MAJOR_VERSION < 7
+zend_object_value php_krb5_kadm5_tldata_object_new(zend_class_entry *ce TSRMLS_DC)
+{
+	zend_object_value retval;
+	krb5_kadm5_tldata_object *object;
+	extern zend_object_handlers krb5_kadm5_tldata_handlers;
+
+	object = emalloc(sizeof(krb5_kadm5_tldata_object));
+
+	memset(&object->data, 0, sizeof(krb5_tl_data));
+
+	zend_object_std_init(&(object->std), ce TSRMLS_CC);
+
+#if PHP_VERSION_ID < 50399
+	zend_hash_copy(object->std.properties, &ce->default_properties,
+					(copy_ctor_func_t) zval_add_ref, NULL,
+					sizeof(zval*));
+#else
+	object_properties_init(&(object->std), ce);
+#endif
+
+	retval.handle = zend_objects_store_put(object, php_krb5_kadm5_tldata_object_dtor, \
NULL, NULL TSRMLS_CC); +	retval.handlers = &krb5_kadm5_tldata_handlers;
+	return retval;
+}
+#else
+zend_object* php_krb5_kadm5_tldata_object_new(zend_class_entry *ce TSRMLS_DC)
+{
+	krb5_kadm5_tldata_object *object = ecalloc(1, sizeof(krb5_kadm5_tldata_object) + \
zend_object_properties_size(ce)); +	zend_object_std_init(&object->std, ce TSRMLS_CC);
+	object_properties_init(&object->std, ce);
+	object->std.handlers = &krb5_kadm5_tldata_handlers;
+	return &object->std;
+}
+#endif
+
+
+/* {{{ proto KADM5TLData KADM5TLData::__construct( long type [, string data])
+ */
+PHP_METHOD(KADM5TLData, __construct)
+{
+	zend_long type = 0;
+	char *data;
+	strsize_t data_len = 0;
+
+	KRB5_SET_ERROR_HANDLING(EH_THROW);
+	if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls", &type, &data, &data_len) \
== FAILURE) { +		RETURN_NULL();
+	}
+	KRB5_SET_ERROR_HANDLING(EH_NORMAL);
+
+
+	krb5_kadm5_tldata_object *tldata = KRB5_THIS_KADM_TLDATA;
+
+	tldata->data.tl_data_type = type;
+	tldata->data.tl_data_length = data_len;
+	tldata->data.tl_data_contents = emalloc(data_len);
+	memcpy(tldata->data.tl_data_contents, data, data_len);
+}
+/* }}} */
+
+/* {{{ proto long KADM5TLData::getType()
+ */
+PHP_METHOD(KADM5TLData, getType)
+{
+	krb5_kadm5_tldata_object *tldata = KRB5_THIS_KADM_TLDATA;
+
+	RETURN_LONG(tldata->data.tl_data_type);
+}
+/* }}} */
+
+/* {{{ proto string KADM5TLData::getData()
+ */
+PHP_METHOD(KADM5TLData, getData)
+{
+	krb5_kadm5_tldata_object *tldata = KRB5_THIS_KADM_TLDATA;
+
+	_RETVAL_STRINGL((char*)tldata->data.tl_data_contents, tldata->data.tl_data_length);
+}
+/* }}} */
+
+
+void php_krb5_kadm5_tldata_to_array(zval* array, krb5_tl_data *data, krb5_int16 num \
TSRMLS_DC) { +	krb5_tl_data *cur = data;
+	int n = num;
+	while ( n > 0 && cur ) {
+		zval *entry = ecalloc(1, sizeof(zval));
+		_ALLOC_INIT_ZVAL(entry);
+		object_init_ex(entry, krb5_ce_kadm5_tldata);
+		krb5_kadm5_tldata_object *tldata = KRB5_KADM_TLDATA(entry);
+		tldata->data.tl_data_type = cur->tl_data_type;
+		tldata->data.tl_data_length = cur->tl_data_length;
+		tldata->data.tl_data_contents = emalloc(cur->tl_data_length);
+		memcpy(tldata->data.tl_data_contents, cur->tl_data_contents, cur->tl_data_length);
+		add_next_index_zval(array, entry);
+		//zval_ptr_dtor(entry);
+		cur = cur->tl_data_next;
+		n--;
+	}
+}
+
+void php_krb5_kadm5_tldata_free(krb5_tl_data *data, krb5_int16 count TSRMLS_DC) {
+	 krb5_tl_data *cur = data;
+	 krb5_tl_data *last = NULL;
+         int n = count;
+	 while ( n > 0 && cur ) {
+	 	if ( cur->tl_data_contents ) {
+			free(cur->tl_data_contents);
+		}
+		last = cur;
+	 	cur = cur->tl_data_next;
+                n--;
+		free(last);
+	 }
+}
+
+krb5_tl_data* php_krb5_kadm5_tldata_from_array(zval *array, krb5_int16* count \
TSRMLS_DC) { +
+	HashTable *arr_hash = Z_ARRVAL_P(array);
+	int have_count = 0;
+	krb5_tl_data *head = NULL;
+	krb5_tl_data *cur = NULL;
+
+#if PHP_MAJOR_VERSION < 7
+	HashPosition pointer;
+	zval **entryp;
+	for(	zend_hash_internal_pointer_reset_ex(arr_hash, &pointer);
+		zend_hash_get_current_data_ex(arr_hash, (void**) &entryp, &pointer) == SUCCESS;
+		zend_hash_move_forward_ex(arr_hash, &pointer)) {
+
+		zval *entry = *entryp;
+#else
+	zval *entry;
+	ZEND_HASH_FOREACH_VAL(arr_hash, entry) {
+#endif
+		if ( Z_TYPE_P(entry) != IS_OBJECT || Z_OBJCE_P(entry) != krb5_ce_kadm5_tldata ) {
+			continue;
+		}
+
+		krb5_tl_data *last = cur;
+		cur = malloc(sizeof(krb5_tl_data));
+		memset(cur, 0, sizeof(krb5_tl_data));
+		if ( last ) {
+			last->tl_data_next = cur;
+		}
+		krb5_kadm5_tldata_object *tldata = KRB5_KADM_TLDATA(entry);
+		cur->tl_data_type = tldata->data.tl_data_type;
+		cur->tl_data_length = tldata->data.tl_data_length;
+		cur->tl_data_contents = malloc(tldata->data.tl_data_length);
+		memcpy(cur->tl_data_contents, tldata->data.tl_data_contents, \
tldata->data.tl_data_length); +		have_count++;
+		if ( head == NULL ) {
+			head = cur;
+		}
+#if PHP_MAJOR_VERSION < 7
+	}
+#else
+	} ZEND_HASH_FOREACH_END();
+#endif
+	*count = have_count;
+	return head;
+}
+
+
+

Copied: pecl/krb5/tags/krb5-1.1.0/trunk/krb5.c (from rev 339675, \
pecl/krb5/trunk/krb5.c) \
                ===================================================================
--- pecl/krb5/tags/krb5-1.1.0/trunk/krb5.c	                        (rev 0)
+++ pecl/krb5/tags/krb5-1.1.0/trunk/krb5.c	2016-07-16 14:46:31 UTC (rev 339676)
@@ -0,0 +1,1378 @@
+/**
+* Copyright (c) 2008 Moritz Bechler
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+* THE SOFTWARE.
+**/
+
+/* CHANGELOG (more recent on top)
+ *
+ * 2010-05-27 Mark Seecof	add getPrincipal(), getRealm(), getLifetime(),
+ * 				renew(), getTktAttrs() methods; support more
+ * 				options to initKeytab/Password(); check only
+ * 				primary TGT in isValid(); fix some bugs.
+ *
+ * 2010-04-11 Moritz Bechler	RC2 release
+ */
+
+#include "config.h"
+#include "php_krb5.h"
+#include "compat.h"
+
+#include "ext/standard/info.h"
+#include "ext/standard/base64.h"
+
+#include <sys/time.h>
+#include <arpa/inet.h>
+
+#ifdef HAVE_KADM5
+#include "kdb.h"
+#endif
+
+
+/* Class definition */
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_KRB5CCache_none, 0, 0, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_KRB5CCache_initPassword, 0, 0, 2)
+	ZEND_ARG_INFO(0, principal)
+	ZEND_ARG_INFO(0, pass)
+	ZEND_ARG_ARRAY_INFO(0, options, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_KRB5CCache_initKeytab, 0, 0, 2)
+	ZEND_ARG_INFO(0, principal)
+	ZEND_ARG_INFO(0, keytab)
+	ZEND_ARG_ARRAY_INFO(0, options, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_KRB5CCache_open, 0, 0, 1)
+	ZEND_ARG_INFO(0, src)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_KRB5CCache_save, 0, 0, 1)
+	ZEND_ARG_INFO(0, dest)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_KRB5CCache_isValid, 0, 0, 0)
+	ZEND_ARG_INFO(0, timeRemain)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_KRB5CCache_getTktAttrs, 0, 0, 0)
+	ZEND_ARG_INFO(0, prefix)
+ZEND_END_ARG_INFO()
+
+PHP_METHOD(KRB5CCache, initPassword);
+PHP_METHOD(KRB5CCache, initKeytab);
+PHP_METHOD(KRB5CCache, getName);
+PHP_METHOD(KRB5CCache, getPrincipal);
+PHP_METHOD(KRB5CCache, getRealm);
+PHP_METHOD(KRB5CCache, getLifetime);
+PHP_METHOD(KRB5CCache, getEntries);
+PHP_METHOD(KRB5CCache, open);
+PHP_METHOD(KRB5CCache, save);
+PHP_METHOD(KRB5CCache, isValid);
+PHP_METHOD(KRB5CCache, getTktAttrs);
+PHP_METHOD(KRB5CCache, renew);
+
+static zend_function_entry krb5_ccache_functions[] = {
+		PHP_ME(KRB5CCache, initPassword, arginfo_KRB5CCache_initPassword, ZEND_ACC_PUBLIC)
+		PHP_ME(KRB5CCache, initKeytab,   arginfo_KRB5CCache_initKeytab,   ZEND_ACC_PUBLIC)
+		PHP_ME(KRB5CCache, getName,      arginfo_KRB5CCache_none,         ZEND_ACC_PUBLIC)
+		PHP_ME(KRB5CCache, getPrincipal, arginfo_KRB5CCache_none,         ZEND_ACC_PUBLIC)
+		PHP_ME(KRB5CCache, getRealm,     arginfo_KRB5CCache_none,         ZEND_ACC_PUBLIC)
+		PHP_ME(KRB5CCache, getLifetime,  arginfo_KRB5CCache_none,         ZEND_ACC_PUBLIC)
+		PHP_ME(KRB5CCache, getEntries,   arginfo_KRB5CCache_none,         ZEND_ACC_PUBLIC)
+		PHP_ME(KRB5CCache, open,         arginfo_KRB5CCache_open,         ZEND_ACC_PUBLIC)
+		PHP_ME(KRB5CCache, save,         arginfo_KRB5CCache_save,         ZEND_ACC_PUBLIC)
+		PHP_ME(KRB5CCache, isValid,      arginfo_KRB5CCache_isValid,      ZEND_ACC_PUBLIC)
+		PHP_ME(KRB5CCache, getTktAttrs,  arginfo_KRB5CCache_getTktAttrs,  ZEND_ACC_PUBLIC)
+		PHP_ME(KRB5CCache, renew,        arginfo_KRB5CCache_none,         ZEND_ACC_PUBLIC)
+		PHP_FE_END
+};
+
+
+zend_module_entry krb5_module_entry = {
+#if ZEND_MODULE_API_NO >= 20010901
+    STANDARD_MODULE_HEADER,
+#endif
+    PHP_KRB5_EXT_NAME,
+    NULL,
+    PHP_MINIT(krb5),
+    PHP_MSHUTDOWN(krb5),
+    NULL,
+    NULL,
+    PHP_MINFO(krb5),
+#if ZEND_MODULE_API_NO >= 20010901
+    PHP_KRB5_VERSION,
+#endif
+    STANDARD_MODULE_PROPERTIES
+};
+
+#ifdef COMPILE_DL_KRB5
+	ZEND_GET_MODULE(krb5)
+#endif
+
+
+krb5_error_code php_krb5_display_error(krb5_context ctx, krb5_error_code code, char* \
str TSRMLS_DC); +
+/*  Initialization functions */
+zend_object_handlers krb5_ccache_handlers;
+
+#if PHP_MAJOR_VERSION < 7
+zend_object_value php_krb5_ticket_object_new( zend_class_entry *ce TSRMLS_DC);
+#else
+zend_object *php_krb5_ticket_object_new(zend_class_entry *ce TSRMLS_DC);
+static void php_krb5_ccache_object_free(zend_object *obj TSRMLS_DC);
+#endif
+
+PHP_MINIT_FUNCTION(krb5)
+{
+	zend_class_entry krb5_ccache;
+
+	INIT_CLASS_ENTRY(krb5_ccache, "KRB5CCache", krb5_ccache_functions);
+	krb5_ce_ccache = zend_register_internal_class(&krb5_ccache TSRMLS_CC);
+	krb5_ce_ccache->create_object = php_krb5_ticket_object_new;
+	memcpy(&krb5_ccache_handlers, zend_get_std_object_handlers(), \
sizeof(zend_object_handlers)); +#if PHP_MAJOR_VERSION >= 7
+	krb5_ccache_handlers.offset = XtOffsetOf(krb5_ccache_object, std);
+	krb5_ccache_handlers.free_obj = php_krb5_ccache_object_free;
+#endif
+
+#ifdef HAVE_KADM5
+	if(php_krb5_kadm5_register_classes(TSRMLS_C) != SUCCESS) {
+		return FAILURE;
+	}
+#endif
+
+	/* register constants */
+	REGISTER_LONG_CONSTANT("GSS_C_DELEG_FLAG", GSS_C_DELEG_FLAG, CONST_CS | \
CONST_PERSISTENT ); +	REGISTER_LONG_CONSTANT("GSS_C_MUTUAL_FLAG", GSS_C_MUTUAL_FLAG, \
CONST_CS | CONST_PERSISTENT ); +	REGISTER_LONG_CONSTANT("GSS_C_REPLAY_FLAG", \
GSS_C_REPLAY_FLAG, CONST_CS | CONST_PERSISTENT ); \
+	REGISTER_LONG_CONSTANT("GSS_C_SEQUENCE_FLAG", GSS_C_SEQUENCE_FLAG, CONST_CS | \
CONST_PERSISTENT ); +	REGISTER_LONG_CONSTANT("GSS_C_CONF_FLAG", GSS_C_CONF_FLAG, \
CONST_CS | CONST_PERSISTENT ); +	REGISTER_LONG_CONSTANT("GSS_C_INTEG_FLAG", \
GSS_C_INTEG_FLAG, CONST_CS | CONST_PERSISTENT ); \
+	REGISTER_LONG_CONSTANT("GSS_C_ANON_FLAG", GSS_C_ANON_FLAG, CONST_CS | \
CONST_PERSISTENT ); +	REGISTER_LONG_CONSTANT("GSS_C_PROT_READY_FLAG", \
GSS_C_PROT_READY_FLAG, CONST_CS | CONST_PERSISTENT ); \
+	REGISTER_LONG_CONSTANT("GSS_C_TRANS_FLAG", GSS_C_TRANS_FLAG, CONST_CS | \
CONST_PERSISTENT ); +
+	REGISTER_LONG_CONSTANT("GSS_C_BOTH", GSS_C_BOTH, CONST_CS | CONST_PERSISTENT );
+	REGISTER_LONG_CONSTANT("GSS_C_INITIATE", GSS_C_INITIATE, CONST_CS | \
CONST_PERSISTENT ); +	REGISTER_LONG_CONSTANT("GSS_C_ACCEPT", GSS_C_ACCEPT, CONST_CS | \
CONST_PERSISTENT ); +
+#ifdef KRB5_TL_DB_ARGS
+	REGISTER_LONG_CONSTANT("KRB5_TL_DB_ARGS", KRB5_TL_DB_ARGS, CONST_CS | \
CONST_PERSISTENT ); +#endif
+
+	if(php_krb5_gssapi_register_classes(TSRMLS_C) != SUCCESS) {
+		return FAILURE;
+	}
+
+	if(php_krb5_negotiate_auth_register_classes(TSRMLS_C) != SUCCESS) {
+		return FAILURE;
+	}
+
+	return SUCCESS;
+}
+
+PHP_MSHUTDOWN_FUNCTION(krb5)
+{
+	if(php_krb5_gssapi_shutdown(TSRMLS_C) != SUCCESS) {
+		return FAILURE;
+	}
+
+	return SUCCESS;
+}
+
+
+PHP_MINFO_FUNCTION(krb5)
+{
+	php_info_print_table_start();
+	php_info_print_table_row(2, "Kerberos 5 support", "enabled");
+	php_info_print_table_row(2, "Extension version", PHP_KRB5_VERSION);
+#ifdef HAVE_KRB5_MIT
+	php_info_print_table_row(2, "Kerberos library", "MIT");
+#endif
+
+#ifdef HAVE_KRB5_HEIMDAL
+	php_info_print_table_row(2, "Kerberos library", "Heimdal");
+#endif
+
+#ifdef KRB5_VERSION
+	php_info_print_table_row(2, "Library version", KRB5_VERSION);
+#endif
+
+#ifdef HAVE_KADM5
+	php_info_print_table_row(2, "KADM5 support", "yes");
+#else
+	php_info_print_table_row(2, "KADM5 support", "no");
+#endif
+
+	php_info_print_table_row(2, "GSSAPI/SPNEGO auth support", "yes");
+	php_info_print_table_end();
+}
+
+/*  Constructors/Destructors */
+/* {{{ */
+#if PHP_MAJOR_VERSION < 7
+static void php_krb5_ccache_object_dtor(void *obj, zend_object_handle handle \
TSRMLS_DC) +{
+	krb5_ccache_object *ticket = (krb5_ccache_object*)obj;
+
+
+	if(ticket) {
+		OBJECT_STD_DTOR(ticket->std);
+
+		krb5_cc_destroy(ticket->ctx, ticket->cc);
+		krb5_free_context(ticket->ctx);
+
+		if(ticket->keytab) {
+			efree(ticket->keytab);
+		}
+
+		efree(ticket);
+	}
+}
+#else
+static void php_krb5_ccache_object_free(zend_object *obj TSRMLS_DC)
+{
+	krb5_ccache_object *ticket = (krb5_ccache_object*)((char *)obj - \
XtOffsetOf(krb5_ccache_object, std)); +	krb5_cc_destroy(ticket->ctx, ticket->cc);
+	krb5_free_context(ticket->ctx);
+
+	if(ticket->keytab) {
+		efree(ticket->keytab);
+	}
+	zend_object_std_dtor(obj);
+}
+#endif
+/* }}} */
+
+
+/* {{{ */
+#if PHP_MAJOR_VERSION < 7
+zend_object_value php_krb5_ticket_object_new(zend_class_entry *ce TSRMLS_DC)
+{
+	zend_object_value retval;
+	krb5_ccache_object *object;
+	krb5_error_code ret = 0;
+
+	object = emalloc(sizeof(krb5_ccache_object));
+	memset(object, 0, sizeof(krb5_ccache_object));
+
+	/* intialize context */
+	if((ret = krb5_init_context(&object->ctx))) {
+		zend_throw_exception(NULL, "Cannot initialize Kerberos5 context",0 TSRMLS_CC);
+	}
+
+	// initialize random ccache
+	if((ret = krb5_cc_new_unique(object->ctx, "MEMORY", "", &object->cc))) {
+		const char *msg = krb5_get_error_message(object->ctx,ret);
+		zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "Cannot open credential cache (%s)", \
msg, ret); +		krb5_free_error_message(object->ctx, msg);
+		krb5_free_context(object->ctx);
+		efree(object);
+		return retval;
+	}
+
+
+	INIT_STD_OBJECT(object->std, ce);
+#if PHP_VERSION_ID < 50399
+	zend_hash_copy(object->std.properties, &ce->default_properties,
+	        		(copy_ctor_func_t) zval_add_ref, NULL,
+					sizeof(zval*));
+#else
+	object_properties_init(&(object->std), ce);
+#endif
+
+	retval.handle = zend_objects_store_put(object, php_krb5_ccache_object_dtor, NULL, \
NULL TSRMLS_CC); +	retval.handlers = &krb5_ccache_handlers;
+	return retval;
+}
+#else
+zend_object *php_krb5_ticket_object_new(zend_class_entry *ce TSRMLS_DC)
+{
+	krb5_ccache_object *object;
+	krb5_error_code ret = 0;
+
+	object = ecalloc(1, sizeof(krb5_ccache_object) + zend_object_properties_size(ce));
+
+	/* intialize context */
+	if((ret = krb5_init_context(&object->ctx))) {
+		zend_throw_exception(NULL, "Cannot initialize Kerberos5 context",0 TSRMLS_CC);
+	}
+
+	// initialize random ccache
+	if((ret = krb5_cc_new_unique(object->ctx, "MEMORY", "", &object->cc))) {
+		const char *msg = krb5_get_error_message(object->ctx,ret);
+		zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "Cannot open credential cache (%s)", \
msg, ret); +		krb5_free_error_message(object->ctx, msg);
+	}
+
+	zend_object_std_init(&object->std, ce TSRMLS_CC);
+	object_properties_init(&object->std, ce);
+	object->std.handlers = &krb5_ccache_handlers;
+	return &object->std;
+}
+#endif
+/* }}} */
+
+/* Helper functions */
+/* {{{ Parse options array for initKeytab()/initPassword() */
+static int php_krb5_parse_init_creds_opts(zval *opts, krb5_get_init_creds_opt \
*cred_opts, char **in_tkt_svc, char **vfy_keytab TSRMLS_DC) +{
+	int retval = 0;
+	zval *tmp = NULL;
+	zend_string *str = NULL;
+
+	if (Z_TYPE_P(opts) != IS_ARRAY) {
+		return KRB5KRB_ERR_GENERIC;
+	}
+
+	/* forwardable */
+	tmp = zend_compat_hash_find(HASH_OF(opts), "forwardable", sizeof("forwardable"));
+	if (tmp != NULL) {
+		krb5_get_init_creds_opt_set_forwardable(cred_opts, zval_is_true(tmp));
+	}
+
+
+	/* proxiable */
+	tmp = zend_compat_hash_find(HASH_OF(opts), "proxiable", sizeof("proxiable"));
+	if (tmp != NULL) {
+		krb5_get_init_creds_opt_set_proxiable(cred_opts, zval_is_true(tmp));
+	}
+
+#ifdef HAVE_KRB5_INIT_CREDS_CANONICALIZE
+	/* canonicalize */
+	tmp = zend_compat_hash_find(HASH_OF(opts), "canonicalize", sizeof("canonicalize"));
+	if (tmp != NULL) {
+		krb5_get_init_creds_opt_set_canonicalize(cred_opts, zval_is_true(tmp));
+	}
+#endif /* HAVE_KRB5_INIT_CREDS_CANONICALIZE */
+
+	/* tkt_life */
+	tmp = zend_compat_hash_find(HASH_OF(opts), "tkt_life", sizeof("tkt_life"));
+	if (tmp != NULL) {
+		krb5_get_init_creds_opt_set_tkt_life(cred_opts, zval_get_long(tmp TSRMLS_CC));
+	}
+
+	/* renew_life */
+	tmp = zend_compat_hash_find(HASH_OF(opts), "renew_life", sizeof("renew_life"));
+	if (tmp != NULL) {
+		krb5_get_init_creds_opt_set_renew_life(cred_opts, zval_get_long(tmp TSRMLS_CC));
+	}
+
+	/* service_name (krb5 arg "in_tkt_service") */
+	tmp = zend_compat_hash_find(HASH_OF(opts), "service_name", sizeof("service_name"));
+	if (tmp != NULL) {
+		str = zval_get_string(tmp TSRMLS_CC);
+		if ((*in_tkt_svc = emalloc(1+str->len))) {
+			strncpy(*in_tkt_svc, str->val, str->len);
+			(*in_tkt_svc)[str->len] = '\0';
+		}
+
+		zend_string_release(str);
+	}
+
+	/* verification keytab name */
+	tmp = zend_compat_hash_find(HASH_OF(opts), "verify_keytab", \
sizeof("verify_keytab")); +	if (tmp != NULL) {
+		str = zval_get_string(tmp TSRMLS_CC);
+		if ((*vfy_keytab = emalloc(1+str->len))) {
+			strncpy(*vfy_keytab, str->val, str->len);
+			(*vfy_keytab)[str->len] = '\0';
+		}
+
+		zend_string_release(str);
+	}
+
+	return retval;
+} /* }}} */
+
+/* {{{ */
+krb5_error_code php_krb5_display_error(krb5_context ctx, krb5_error_code code, char* \
str TSRMLS_DC) { +	const char *errstr = krb5_get_error_message(ctx,code);
+	zend_throw_exception_ex(NULL, 0 TSRMLS_CC, str, errstr);
+	krb5_free_error_message(ctx, errstr);
+	return code;
+}
+/* }}} */
+
+/* {{{  Copies one ccache to another*/
+static krb5_error_code php_krb5_copy_ccache(krb5_context ctx, const krb5_ccache src, \
krb5_ccache dest TSRMLS_DC) +{
+	krb5_error_code retval = 0;
+	krb5_principal princ;
+
+	if((retval = krb5_cc_get_principal(ctx,src,&princ))) {
+		return php_krb5_display_error(ctx, retval,  "Failed to retrieve principal from \
source ccache (%s)" TSRMLS_CC); +	}
+
+	if((retval = krb5_cc_initialize(ctx,dest,princ))) {
+		krb5_free_principal(ctx, princ);
+		return php_krb5_display_error(ctx, retval,  "Failed to initialize destination \
ccache (%s)" TSRMLS_CC); +	}
+
+	krb5_free_principal(ctx, princ);
+
+
+#ifdef HAVE_KRB5_HEIMDAL
+	if((retval = krb5_cc_copy_cache(ctx, src, dest))) {
+		return php_krb5_display_error(ctx, retval,  "Cannot copy given credential cache \
(%s)" TSRMLS_CC); +	}
+#else
+	krb5_cc_cursor cursor;
+	if((retval = krb5_cc_start_seq_get(ctx,src,&cursor))) {
+		return retval;
+	}
+
+	krb5_creds creds;
+	while(krb5_cc_next_cred(ctx,src,&cursor,&creds) == 0) {
+		if((retval = krb5_cc_store_cred(ctx, dest,&creds))) {
+			krb5_cc_end_seq_get(ctx,src,&cursor);
+			return retval;
+		}
+		krb5_free_cred_contents(ctx, &creds);
+	}
+
+	krb5_cc_end_seq_get(ctx,src,&cursor);
+#endif
+
+	return retval;
+}
+/* }}} */
+
+
+/* {{{ extract realm string */
+static char *php_krb5_get_realm(krb5_context ctx, krb5_principal princ TSRMLS_DC)
+{
+#ifdef HAVE_KRB5_PRINCIPAL_GET_REALM
+	return krb5_principal_get_realm(ctx, princ);
+#else
+	krb5_data *data;
+
+	data = krb5_princ_realm(ctx, princ);
+	if ((data != NULL) && (data->data != NULL)) return data->data;
+	/* else */
+	return NULL;
+#endif
+}
+/* }}} */
+
+/* {{{ Get expiration times for primary TGT in cache */
+static krb5_error_code php_krb5_get_tgt_expire(krb5_ccache_object *ccache, long \
*endtime, long *renew_until TSRMLS_DC) +{
+	krb5_error_code retval = 0;
+	char *errstr = NULL;
+	krb5_principal princ;
+	int have_princ = 0;
+	krb5_creds in_cred;
+	int have_in_cred = 0;
+	krb5_creds *credptr = NULL;
+	int have_credptr = 0;
+	char *realm;
+
+	do {
+		memset(&princ, 0, sizeof(princ));
+		if ((retval = krb5_cc_get_principal(ccache->ctx,ccache->cc, &princ))) {
+			errstr = "Failed to retrieve principal from source ccache (%s)";
+			break;
+		}
+		have_princ = 1;
+
+		if (!(realm = php_krb5_get_realm(ccache->ctx, princ TSRMLS_CC))) {
+			retval = KRB5KRB_ERR_GENERIC;
+			errstr = "Failed to extract realm from principal (%s)";
+			break;
+		}
+
+		memset(&in_cred, 0, sizeof(in_cred));
+		in_cred.client = princ;
+
+		if ((retval = krb5_build_principal(ccache->ctx, &in_cred.server, strlen(realm), \
realm, "krbtgt", realm, NULL))) { +			errstr = "Failed to build krbtgt principal \
(%s)"; +			break;
+		}
+		have_in_cred = 1;
+
+		if ((retval = krb5_get_credentials(ccache->ctx, KRB5_GC_CACHED, ccache->cc, \
&in_cred, &credptr))) { +			errstr = "Failed to retrieve krbtgt ticket from cache \
(%s)"; +			break;
+		}
+		have_credptr = 1;
+
+	} while (0);
+
+	if (have_princ) krb5_free_principal(ccache->ctx, princ);
+	if (have_in_cred) krb5_free_principal(ccache->ctx, in_cred.server);
+
+	if (have_credptr) {
+		krb5_free_cred_contents(ccache->ctx, credptr);
+		*endtime = credptr->times.endtime;
+		*renew_until = credptr->times.renew_till;
+		free(credptr);
+	}
+
+	if (errstr != NULL) {
+		php_krb5_display_error(ccache->ctx, retval, errstr TSRMLS_CC);
+	}
+
+	return retval;
+}
+/* }}} */
+
+/* {{{ verify a (client's) new TGT using keytab */
+static krb5_error_code php_krb5_verify_tgt(krb5_ccache_object *ccache, krb5_creds \
*creds, char *vfy_keytab TSRMLS_DC) +{
+	krb5_error_code retval = 0;
+	krb5_error_code r2val;
+	krb5_keytab ktab;
+	int have_ktab = 0;
+	krb5_kt_cursor cursor;
+	int have_cursor = 0;
+	krb5_keytab_entry entry;
+	int have_entry = 0;
+	krb5_principal princ;
+	int have_princ = 0;
+	krb5_verify_init_creds_opt opts;
+
+
+	if (!vfy_keytab || !*vfy_keytab) {
+		return KRB5_KT_NOTFOUND;
+	}
+
+    do {
+	memset(&ktab, 0, sizeof(ktab));
+	if ((retval = krb5_kt_resolve(ccache->ctx, vfy_keytab, &ktab))) {
+		break;
+	}
+	have_ktab = 1;
+
+	memset(&cursor, 0, sizeof(cursor));
+	if ((retval = krb5_kt_start_seq_get(ccache->ctx, ktab, &cursor))) {
+		break;
+	}
+	have_cursor = 1;
+
+	memset(&entry, 0, sizeof(entry));
+	if ((retval = krb5_kt_next_entry(ccache->ctx, ktab, &entry, &cursor))) {
+		break;
+	}
+	have_entry = 1;
+
+	memset(&princ, 0, sizeof(princ));
+	if ((retval = krb5_copy_principal(ccache->ctx, entry.principal, &princ))) {
+		break;
+	}
+	have_princ = 1;
+
+	krb5_verify_init_creds_opt_init(&opts);
+	krb5_verify_init_creds_opt_set_ap_req_nofail(&opts, 1);
+
+	if ((retval = krb5_verify_init_creds(ccache->ctx, creds, princ, ktab, NULL, \
&opts))) { +		break;
+	}
+    } while (0);
+
+        if (have_ktab && (r2val = krb5_kt_close(ccache->ctx, ktab))) {
+		php_krb5_display_error(ccache->ctx, r2val, "Failed to close keytab (%s)" \
TSRMLS_CC); +	}
+
+	if (have_cursor && (r2val = krb5_kt_end_seq_get(ccache->ctx, ktab, &cursor))) {
+		php_krb5_display_error(ccache->ctx, r2val, "Failed to free keytab cursor (%s)" \
TSRMLS_CC); +	}
+
+	if (have_entry &&
+#ifdef HAVE_KRB5_HEIMDAL
+		(r2val = krb5_kt_free_entry(ccache->ctx, &entry))
+#else
+		(r2val = krb5_free_keytab_entry_contents(ccache->ctx, &entry))
+#endif
+			) {
+		php_krb5_display_error(ccache->ctx, r2val, "Failed to free keytab entry (%s)" \
TSRMLS_CC); +	}
+
+	if (have_princ) krb5_free_principal(ccache->ctx, princ);
+
+	return retval;
+}
+/* }}} */
+
+
+/* KRB5CCache Methods */
+
+/* {{{ proto string KRB5CCache::getName(  )
+   Gets the name/identifier of this credential cache */
+PHP_METHOD(KRB5CCache, getName)
+{
+	krb5_ccache_object *ccache = KRB5_THIS_CCACHE;
+	const char *tmpname = krb5_cc_get_name(ccache->ctx, ccache->cc);
+	const char *tmptype = krb5_cc_get_type(ccache->ctx, ccache->cc);
+	char *name = NULL;
+
+	if (zend_parse_parameters_none() == FAILURE) {
+		zend_throw_exception(NULL, "Failed to parse arglist", 0 TSRMLS_CC);
+		RETURN_FALSE;
+	}
+
+	name = emalloc(strlen(tmpname) + strlen(tmptype) + 2);
+	*name = 0;
+	strcat(name, tmptype);
+	strcat(name, ":");
+	strcat(name, tmpname);
+	_RETVAL_STRING(name);
+	efree(name);
+}
+/* }}} */
+
+/* {{{ proto bool KRB5CCache::open( string $src )
+   Copies the contents of the credential cache given by $dest to this credential \
cache */ +PHP_METHOD(KRB5CCache, open)
+{
+	krb5_ccache_object *ccache = KRB5_THIS_CCACHE;
+	char *sccname = NULL;
+	strsize_t sccname_len = 0;
+	krb5_error_code retval = 0;
+
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, ARG_PATH, &sccname, \
&sccname_len) == FAILURE) { +		zend_throw_exception(NULL, "Failed to parse arglist", \
0 TSRMLS_CC); +		RETURN_FALSE;
+	}
+
+	krb5_ccache src;
+
+	if((retval = krb5_cc_resolve(ccache->ctx, sccname, &src))) {
+		php_krb5_display_error(ccache->ctx, retval,  "Cannot open given credential cache \
(%s)" TSRMLS_CC); +		RETURN_FALSE;
+	}
+
+	if((retval = php_krb5_copy_ccache(ccache->ctx, src, ccache->cc TSRMLS_CC))) {
+		krb5_cc_close(ccache->ctx, src);
+		php_krb5_display_error(ccache->ctx, retval,  "Failed to copy credential cache \
(%s)" TSRMLS_CC); +		RETURN_FALSE;
+	}
+
+	krb5_cc_close(ccache->ctx, src);
+	RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto bool KRB5CCache::save( string $dest )
+   Copies the contents of this credential cache to the credential cache given by \
$dest */ +PHP_METHOD(KRB5CCache, save)
+{
+	krb5_ccache_object *ccache = KRB5_THIS_CCACHE;
+	char *sccname = NULL;
+	strsize_t sccname_len = 0;
+	krb5_error_code retval = 0;
+
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, ARG_PATH, &sccname, \
&sccname_len) == FAILURE) { +		zend_throw_exception(NULL, "Failed to parse arglist", \
0 TSRMLS_CC); +		RETURN_FALSE;
+	}
+
+	krb5_ccache dest = NULL;
+	if((retval = krb5_cc_resolve(ccache->ctx, sccname, &dest))) {
+		php_krb5_display_error(ccache->ctx, retval,  "Cannot open given credential cache \
(%s)" TSRMLS_CC); +		RETURN_FALSE;
+	}
+
+	if((retval = php_krb5_copy_ccache(ccache->ctx, ccache->cc, dest TSRMLS_CC))) {
+		krb5_cc_close(ccache->ctx, dest);
+		php_krb5_display_error(ccache->ctx, retval,  "Failed to copy credential cache \
(%s)" TSRMLS_CC); +		RETURN_FALSE;
+	}
+
+	krb5_cc_close(ccache->ctx, dest);
+	RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto bool KRB5CCache::initPassword( string $principal, string $pass [, array \
$options ]) +   Gets a TGT for the given principal using the given credentials */
+PHP_METHOD(KRB5CCache, initPassword)
+{
+	krb5_ccache_object *ccache = KRB5_THIS_CCACHE;
+	krb5_error_code retval = 0;
+	char *errstr = "";
+
+	char *sprinc = NULL;
+	strsize_t sprinc_len = 0;
+	char *spass = NULL;
+	strsize_t spass_len = 0;
+	zval *opts = NULL;
+
+	krb5_principal princ;
+	int have_princ = 0;
+	krb5_get_init_creds_opt *cred_opts;
+	int have_cred_opts = 0;
+	char *in_tkt_svc = NULL;
+	char *vfy_keytab = NULL;
+	krb5_creds creds;
+	int have_creds = 0;
+
+#ifndef KRB5_GET_INIT_CREDS_OPT_CANONICALIZE
+	krb5_get_init_creds_opt cred_opts_struct;
+	cred_opts = &cred_opts_struct;
+#endif
+
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|a", &sprinc, &sprinc_len, \
&spass, &spass_len, &opts) == FAILURE) { +		zend_throw_exception(NULL, "Failed to \
parse arglist", 0 TSRMLS_CC); +		RETURN_FALSE;
+	}
+
+    do {
+	memset(&princ, 0, sizeof(princ));
+	if ((retval = krb5_parse_name(ccache->ctx, sprinc, &princ))) {
+		errstr = "Cannot parse Kerberos principal (%s)";
+		break;
+	}
+	have_princ = 1;
+
+#ifdef KRB5_GET_INIT_CREDS_OPT_CANONICALIZE
+	if ((retval = krb5_get_init_creds_opt_alloc(ccache->ctx, &cred_opts))) {
+		errstr = "Cannot allocate cred_opts (%s)";
+		break;
+	}
+#else
+	krb5_get_init_creds_opt_init(cred_opts);
+#endif
+	have_cred_opts = 1;
+
+	if (opts != NULL) {
+		if ((retval = php_krb5_parse_init_creds_opts(opts, cred_opts, &in_tkt_svc, \
&vfy_keytab TSRMLS_CC))) { +			errstr = "Cannot parse credential options (%s)";
+			break;
+		}
+	}
+
+	memset(&creds, 0, sizeof(creds));
+	if ((retval = krb5_get_init_creds_password(ccache->ctx, &creds, princ, spass, NULL, \
0, 0, in_tkt_svc, cred_opts))) { +		errstr = "Cannot get ticket (%s)";
+		break;
+	}
+	have_creds = 1;
+
+	if((retval = krb5_cc_initialize(ccache->ctx, ccache->cc, princ))) {
+		errstr = "Failed to initialize credential cache (%s)";
+		break;
+	}
+
+	if((retval = krb5_cc_store_cred(ccache->ctx, ccache->cc, &creds))) {
+		errstr = "Failed to store ticket in credential cache (%s)";
+		break;
+	}
+
+	if (vfy_keytab && *vfy_keytab && (retval = php_krb5_verify_tgt(ccache, &creds, \
vfy_keytab TSRMLS_CC))) { +		errstr = "Failed to verify ticket (%s)";
+		break;
+	}
+
+    } while (0);
+
+	if (have_princ) krb5_free_principal(ccache->ctx, princ);
+
+#ifdef KRB5_GET_INIT_CREDS_OPT_CANONICALIZE
+	if (have_cred_opts) krb5_get_init_creds_opt_free(ccache->ctx, cred_opts);
+#endif
+
+	if (in_tkt_svc) efree(in_tkt_svc);
+	if (vfy_keytab) efree(vfy_keytab);
+	if (have_creds) krb5_free_cred_contents(ccache->ctx, &creds);
+
+	if (retval) {
+		php_krb5_display_error(ccache->ctx, retval, errstr TSRMLS_CC);
+		RETURN_FALSE;
+	}
+
+	RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto bool KRB5CCache::initKeytab( string $principal, string $keytab_file [, \
array $options ]) +   Gets a TGT for the given principal using the credentials in the \
given keytab */ +PHP_METHOD(KRB5CCache, initKeytab)
+{
+	krb5_ccache_object *ccache = KRB5_THIS_CCACHE;
+	krb5_error_code retval = 0;
+	char *errstr = "";
+
+	char *sprinc = NULL;
+	strsize_t sprinc_len = 0;
+	char *skeytab = NULL;
+	strsize_t skeytab_len = 0;
+	zval *opts = NULL;
+
+	krb5_principal princ;
+	int have_princ = 0;
+	krb5_keytab keytab;
+	int have_keytab = 0;
+	krb5_get_init_creds_opt *cred_opts;
+	int have_cred_opts = 0;
+	char *in_tkt_svc = NULL;
+	char *vfy_keytab = NULL;
+	krb5_creds creds;
+	int have_creds = 0;
+
+#ifndef KRB5_GET_INIT_CREDS_OPT_CANONICALIZE
+	krb5_get_init_creds_opt cred_opts_struct;
+	cred_opts = &cred_opts_struct;
+#endif
+
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s" ARG_PATH "|a", &sprinc, \
&sprinc_len, &skeytab, &skeytab_len, &opts) == FAILURE) { \
+		zend_throw_exception(NULL, "Failed to parse arglist", 0 TSRMLS_CC); \
+		RETURN_FALSE; +	}
+
+#if PHP_VERSION_ID < 50399
+	if ( (PG(safe_mode) &&
+			!php_checkuid(skeytab, NULL, CHECKUID_CHECK_FILE_AND_DIR)) ||
+		php_check_open_basedir(skeytab TSRMLS_CC)) {
+		RETURN_FALSE;
+	}
+#else
+	if ( php_check_open_basedir(skeytab TSRMLS_CC)) {
+		RETURN_FALSE;
+	}
+#endif
+
+    do {
+	memset(&princ, 0, sizeof(princ));
+	if ((retval = krb5_parse_name(ccache->ctx, sprinc, &princ))) {
+		errstr = "Cannot parse Kerberos principal (%s)";
+		break;
+	}
+	have_princ = 1;
+
+	memset(&keytab, 0, sizeof(keytab));
+	if ((retval = krb5_kt_resolve(ccache->ctx, skeytab, &keytab))) {
+		errstr = "Cannot load keytab (%s)";
+		break;
+	}
+	have_keytab = 1;
+
+#ifdef KRB5_GET_INIT_CREDS_OPT_CANONICALIZE
+	if ((retval = krb5_get_init_creds_opt_alloc(ccache->ctx, &cred_opts))) {
+		errstr = "Cannot allocate cred_opts (%s)";
+		break;
+	}
+#else
+	krb5_get_init_creds_opt_init(cred_opts);
+#endif
+	have_cred_opts = 1;
+
+	if(opts) {
+		if ((retval = php_krb5_parse_init_creds_opts(opts, cred_opts, &in_tkt_svc, \
&vfy_keytab TSRMLS_CC))) { +			errstr = "Cannot parse credential options";
+			break;
+		}
+	}
+
+	memset(&creds, 0, sizeof(creds));
+	if ((retval = krb5_get_init_creds_keytab(ccache->ctx, &creds, princ, keytab, 0, \
in_tkt_svc, cred_opts))) { +		errstr = "Cannot get ticket (%s)";
+		break;
+	}
+	have_creds = 1;
+
+	if ((retval = krb5_cc_initialize(ccache->ctx, ccache->cc, princ))) {
+		errstr = "Failed to initialize credential cache (%s)";
+		break;
+	}
+
+	if((retval = krb5_cc_store_cred(ccache->ctx, ccache->cc, &creds))) {
+		errstr = "Failed to store ticket in credential cache (%s)";
+		break;
+	}
+
+	if (vfy_keytab && *vfy_keytab && (retval = php_krb5_verify_tgt(ccache, &creds, \
vfy_keytab TSRMLS_CC))) { +		errstr = "Failed to verify ticket (%s)";
+		break;
+	}
+
+    } while (0);
+
+	if (have_princ) krb5_free_principal(ccache->ctx, princ);
+	if (have_keytab) krb5_kt_close(ccache->ctx, keytab);
+
+#ifdef KRB5_GET_INIT_CREDS_OPT_CANONICALIZE
+	if (have_cred_opts) krb5_get_init_creds_opt_free(ccache->ctx, cred_opts);
+#endif
+
+	if (in_tkt_svc) efree(in_tkt_svc);
+	if (vfy_keytab) efree(vfy_keytab);
+	if (have_creds) krb5_free_cred_contents(ccache->ctx, &creds);
+
+	if (retval) {
+		php_krb5_display_error(ccache->ctx, retval, errstr TSRMLS_CC);
+		RETURN_FALSE;
+	}
+
+	ccache->keytab = estrdup(skeytab);
+	RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto string KRB5CCache::getPrincipal( )
+   Returns name of primary principal (client) associated with cache */
+PHP_METHOD(KRB5CCache, getPrincipal)
+{
+	krb5_ccache_object *ccache = KRB5_THIS_CCACHE;
+	krb5_error_code retval = 0;
+	krb5_principal princ;
+	char *princname = NULL;
+
+	if (zend_parse_parameters_none() == FAILURE) {
+		zend_throw_exception(NULL, "Failed to parse arglist", 0 TSRMLS_CC);
+		RETURN_FALSE;
+	}
+
+	memset(&princ, 0, sizeof(princ));
+	if ((retval = krb5_cc_get_principal(ccache->ctx, ccache->cc, &princ))) {
+		php_krb5_display_error(ccache->ctx, retval, "Failed to retrieve principal from \
source ccache (%s)" TSRMLS_CC); +		RETURN_EMPTY_STRING();
+	}
+
+	if ((retval = krb5_unparse_name(ccache->ctx, princ, &princname))) {
+		krb5_free_principal(ccache->ctx,princ);
+		php_krb5_display_error(ccache->ctx, retval, "Failed to unparse principal name \
(%s)" TSRMLS_CC); +		RETURN_EMPTY_STRING();
+	}
+
+	_RETVAL_STRING(princname);
+	krb5_free_unparsed_name(ccache->ctx,princname);
+	krb5_free_principal(ccache->ctx,princ);
+}
+/* }}} */
+
+/* {{{ proto string KRB5CCache::getRealm( )
+   Returns name of realm for primary principal */
+PHP_METHOD(KRB5CCache, getRealm)
+{
+	krb5_ccache_object *ccache = KRB5_THIS_CCACHE;
+	krb5_error_code retval = 0;
+	krb5_principal princ;
+	char *realm;
+
+	if (zend_parse_parameters_none() == FAILURE) {
+		zend_throw_exception(NULL, "Failed to parse arglist", 0 TSRMLS_CC);
+		RETURN_FALSE;
+	}
+
+	memset(&princ, 0, sizeof(princ));
+	if ((retval = krb5_cc_get_principal(ccache->ctx,ccache->cc,&princ))) {
+		php_krb5_display_error(ccache->ctx, retval, "Failed to retrieve principal from \
source ccache (%s)" TSRMLS_CC); +		RETURN_EMPTY_STRING();
+	}
+
+	if (!(realm = php_krb5_get_realm(ccache->ctx, princ TSRMLS_CC))) {
+		krb5_free_principal(ccache->ctx,princ);
+		php_krb5_display_error(ccache->ctx, KRB5KRB_ERR_GENERIC, "Failed to extract realm \
from principal (%s)" TSRMLS_CC); +		RETURN_EMPTY_STRING();
+	}
+
+	_RETVAL_STRING(realm);
+	krb5_free_principal(ccache->ctx,princ);
+}
+/* }}} */
+
+/* {{{ proto array KRB5CCache::getLifetime( )
+   Return array with primary TGT's endtime and renew_until times in it */
+PHP_METHOD(KRB5CCache, getLifetime)
+{
+	krb5_ccache_object *ccache = KRB5_THIS_CCACHE;
+	krb5_error_code retval = 0;
+	long endtime, renew_until;
+
+	if (zend_parse_parameters_none() == FAILURE) {
+		zend_throw_exception(NULL, "Failed to parse arglist", 0 TSRMLS_CC);
+		RETURN_FALSE;
+	}
+
+	array_init(return_value);
+
+	if ((retval = php_krb5_get_tgt_expire(ccache,&endtime,&renew_until TSRMLS_CC))) {
+		php_krb5_display_error(ccache->ctx, retval, "Failed to get TGT times (%s)" \
TSRMLS_CC); +		return;
+	}
+
+	add_assoc_long(return_value, "endtime", endtime);
+	add_assoc_long(return_value, "renew_until", renew_until);
+}
+/* }}} */
+
+/* {{{ proto array KRB5CCache::getEntries( )
+   Fetches all principal names for which tickets are available in this cache */
+PHP_METHOD(KRB5CCache, getEntries)
+{
+	krb5_ccache_object *ccache = KRB5_THIS_CCACHE;
+	krb5_error_code retval = 0;
+	char *errstr = "";
+	krb5_cc_cursor cursor;
+	int have_cursor = 0;
+	krb5_creds creds;
+	int have_creds = 0;
+	char *princname;
+
+	if (zend_parse_parameters_none() == FAILURE) {
+		zend_throw_exception(NULL, "Failed to parse arglist", 0 TSRMLS_CC);
+		RETURN_FALSE;
+	}
+
+	array_init(return_value);
+
+    do {
+	memset(&cursor, 0, sizeof(cursor));
+	if((retval = krb5_cc_start_seq_get(ccache->ctx,ccache->cc,&cursor))) {
+		errstr = "Failed to initialize ccache iterator (%s)";
+		break;
+	}
+	have_cursor = 1;
+
+	memset(&creds, 0, sizeof(creds));
+	while(krb5_cc_next_cred(ccache->ctx,ccache->cc,&cursor,&creds) == 0) {
+		have_creds = 1;
+		if(creds.server) {
+			princname = NULL;
+			if((retval = krb5_unparse_name(ccache->ctx, creds.server, &princname))) {
+				errstr = "Failed to unparse principal name (%s)";
+				break;
+			}
+			_add_next_index_string(return_value, princname);
+			krb5_free_unparsed_name(ccache->ctx, princname);
+		}
+		krb5_free_cred_contents(ccache->ctx, &creds);
+		have_creds = 0;
+	}
+
+    } while (0);
+
+	if (have_creds) krb5_free_cred_contents(ccache->ctx, &creds);
+
+	if (have_cursor) krb5_cc_end_seq_get(ccache->ctx, ccache->cc, &cursor);
+
+	if (*errstr) {
+		php_krb5_display_error(ccache->ctx, retval, errstr TSRMLS_CC);
+		array_init(return_value);
+	}
+}
+/* }}} */
+
+/* {{{ proto bool KRB5CCache::isValid( [ int $timeRemain = 0 ] )
+   Checks whether the primary TGT in the cache is still valid and will remain valid \
for the given number of seconds */ +PHP_METHOD(KRB5CCache, isValid)
+{
+	krb5_ccache_object *ccache = KRB5_THIS_CCACHE;
+	krb5_error_code retval = 0;
+	long endtime, renew_until, then;
+	krb5_timestamp now;
+	zend_long need = 0;
+
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &need) == FAILURE) {
+		zend_throw_exception(NULL, "Failed to parse arglist", 0 TSRMLS_CC);
+		RETURN_FALSE;
+	}
+
+	if ((retval = php_krb5_get_tgt_expire(ccache,&endtime,&renew_until TSRMLS_CC))) {
+		RETURN_FALSE;
+	}
+
+	if((retval = krb5_timeofday(ccache->ctx, &now))) {
+		php_krb5_display_error(ccache->ctx, retval, "Failed to obtain time (%s)" \
TSRMLS_CC); +	}
+
+	then = now + need + 60; /* modest allowance for clock drift */
+
+	if (then > endtime) {
+			RETURN_FALSE;
+		}
+
+	RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto array KRB5CCache::getTktAttrs( [string prefix])
+   Fetches principals and (readable) attributes of ticket(s) in cache */
+PHP_METHOD(KRB5CCache, getTktAttrs)
+{
+	krb5_ccache_object *ccache = KRB5_THIS_CCACHE;
+	krb5_error_code retval = 0;
+	char *errstr = "";
+	krb5_cc_cursor cursor;
+	int have_cursor = 0;
+	krb5_creds creds;
+	int have_creds = 0;
+	_DECLARE_ZVAL(tktinfo);
+	char *princname;
+	long princ_len;
+	long tktflags;
+	char strflags[65];
+	char *q = strflags + sizeof(strflags) - 1;
+	char *p;
+	krb5_ticket *tkt;
+	char *encstr;
+#define ENCSTRMAX 256
+	krb5_address *tktaddr, **tkt_addrs;
+	zval *addrlist = NULL;
+	struct in_addr ipaddr;
+#ifdef INET6_ADDRSTRLEN
+	struct in6_addr ip6addr;
+	char straddr[INET6_ADDRSTRLEN];
+#endif
+	char *prefix = NULL;
+	strsize_t pfx_len = 0;
+
+	array_init(return_value);
+
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &prefix, &pfx_len) == \
FAILURE) { +		return;
+	}
+	if (pfx_len == 0) prefix = NULL;
+
+    do {
+	memset(&cursor, 0, sizeof(cursor));
+	if ((retval = krb5_cc_start_seq_get(ccache->ctx,ccache->cc,&cursor))) {
+		errstr = "Failed to initialize ccache iterator (%s)";
+		break;
+	}
+	have_cursor = 1;
+
+	memset(&creds, 0, sizeof(creds));
+	while (krb5_cc_next_cred(ccache->ctx,ccache->cc,&cursor,&creds) == 0) {
+		have_creds = 1;
+		if (creds.server) {
+			_ALLOC_INIT_ZVAL(tktinfo);
+			array_init(tktinfo);
+
+			princname = NULL;
+			if ((retval = krb5_unparse_name(ccache->ctx, creds.server, &princname))) {
+				errstr = "Failed to unparse server principal name (%s)";
+				break;
+			}
+
+			princ_len = princname ? strlen(princname) : 0;
+			if (prefix && ((princ_len < pfx_len) || strncmp(princname,prefix,pfx_len))) {
+				free(princname);
+				krb5_free_cred_contents(ccache->ctx, &creds);
+				have_creds = 0;
+				continue;
+			}
+
+			_add_assoc_string(tktinfo, "server", (princname?princname:""));
+
+			krb5_free_unparsed_name(ccache->ctx, princname);
+
+			princname = NULL;
+			if((retval = krb5_unparse_name(ccache->ctx, creds.client, &princname))) {
+				errstr = "Failed to unparse client principal name (%s)";
+				break;
+			}
+			_add_assoc_string(tktinfo, "client", (princname?princname:""));
+			krb5_free_unparsed_name(ccache->ctx, princname);
+
+			add_assoc_long(tktinfo, "authtime", creds.times.authtime);
+			add_assoc_long(tktinfo, "starttime", creds.times.starttime);
+			add_assoc_long(tktinfo, "endtime", creds.times.endtime);
+
+			/* Darn it, "till" is NOT an abbreviation of "until" */
+			add_assoc_long(tktinfo, "renew_until", creds.times.renew_till);
+
+			tktflags = creds.ticket_flags;
+			p = strflags;
+			*p = '\0';
+			if ((tktflags & TKT_FLG_FORWARDABLE) && (p < q)) *(p++) = 'F';
+			if ((tktflags & TKT_FLG_FORWARDED) && (p < q)) *(p++) = 'f';
+			if ((tktflags & TKT_FLG_PROXIABLE) && (p < q)) *(p++) = 'P';
+			if ((tktflags & TKT_FLG_PROXY) && (p < q)) *(p++) = 'p';
+			if ((tktflags & TKT_FLG_MAY_POSTDATE) && (p < q)) *(p++) = 'D';
+			if ((tktflags & TKT_FLG_POSTDATED) && (p < q)) *(p++) = 'd';
+			if ((tktflags & TKT_FLG_INVALID) && (p < q)) *(p++) = 'i';
+			if ((tktflags & TKT_FLG_RENEWABLE) && (p < q)) *(p++) = 'R';
+			if ((tktflags & TKT_FLG_INITIAL) && (p < q)) *(p++) = 'I';
+			if ((tktflags & TKT_FLG_PRE_AUTH) && (p < q)) *(p++) = 'A';
+			if ((tktflags & TKT_FLG_HW_AUTH) && (p < q)) *(p++) = 'H';
+		if ((tktflags & TKT_FLG_TRANSIT_POLICY_CHECKED) && (p < q)) *(p++) = 'T';
+			if ((tktflags & TKT_FLG_OK_AS_DELEGATE) && (p < q)) *(p++) = 'O';
+#ifdef TKT_FLG_ENC_PA_REP
+			if ((tktflags & TKT_FLG_ENC_PA_REP) && (p < q)) *(p++) = 'e';
+#endif
+			if ((tktflags & TKT_FLG_ANONYMOUS) && (p < q)) *(p++) = 'a';
+			*p = '\0';
+
+			_add_assoc_string(tktinfo, "flags", strflags);
+
+#ifdef HAVE_KRB5_HEIMDAL
+			encstr = NULL;
+			if ((retval = krb5_enctype_to_string(ccache->ctx,creds.keyblock.enctype, \
&encstr))) +#else
+			encstr = malloc(ENCSTRMAX);
+			if ((retval = krb5_enctype_to_string(creds.keyblock.enctype, encstr, ENCSTRMAX)))
+#endif
+			{
+				if (!encstr) encstr = malloc(ENCSTRMAX);
+				snprintf(encstr, ENCSTRMAX, "enctype %d", creds.keyblock.enctype);
+			}
+			_add_assoc_string(tktinfo, "skey_enc", encstr);
+			free(encstr);
+
+			if ((retval = krb5_decode_ticket(&creds.ticket,&tkt))) {
+				errstr = "Failed to decode ticket data (%s)";
+				break;
+			} else {
+#ifdef HAVE_KRB5_HEIMDAL
+				encstr = NULL;
+				if((retval = krb5_enctype_to_string(ccache->ctx,creds.keyblock.enctype, \
&encstr))) +#else
+				encstr = malloc(ENCSTRMAX);
+				if((retval = krb5_enctype_to_string(tkt->enc_part.enctype, encstr, ENCSTRMAX)))
+#endif
+				{
+					if (!encstr) encstr = malloc(ENCSTRMAX);
+					snprintf(encstr, ENCSTRMAX, "enctype %d", tkt->enc_part.enctype);
+				}
+				_add_assoc_string(tktinfo, "tkt_enc", encstr);
+				free(encstr);
+				krb5_free_ticket(ccache->ctx, tkt);
+			}
+
+			_ALLOC_INIT_ZVAL(addrlist);
+			array_init(addrlist);
+			tkt_addrs = creds.addresses;
+			if (tkt_addrs) while((tktaddr = *(tkt_addrs++))) {
+				if ((tktaddr->addrtype == ADDRTYPE_INET) && (tktaddr->length == 4)) {
+					memcpy(&(ipaddr.s_addr), tktaddr->contents, tktaddr->length);
+
+#ifndef INET6_ADDRSTRLEN
+					_add_next_index_string(addrlist, inet_ntoa(ipaddr));
+				}
+#if 0
+ { match curlies
+#endif
+#else /* ! INET6_ADDRSTRLEN */
+					if (inet_ntop(AF_INET, &ipaddr, straddr, sizeof(straddr))) {
+						_add_next_index_string(addrlist, straddr);
+					}
+				}
+				if ((tktaddr->addrtype == ADDRTYPE_INET6) && (tktaddr->length >= 4)) {
+					memcpy(ip6addr.s6_addr, tktaddr->contents, tktaddr->length);
+					if (inet_ntop(AF_INET6, &ipaddr, straddr, sizeof(straddr))) {
+						_add_next_index_string(addrlist, straddr);
+					}
+				}
+#endif /* INET6_ADDRSTRLEN */
+			}
+			add_assoc_zval(tktinfo, "addresses", addrlist);
+			add_next_index_zval(return_value,tktinfo);
+		}
+
+		krb5_free_cred_contents(ccache->ctx, &creds);
+		have_creds = 0;
+	} /* while creds */
+
+	if (have_creds) krb5_free_cred_contents(ccache->ctx, &creds);
+
+    } while (0);
+
+	if (have_cursor) krb5_cc_end_seq_get(ccache->ctx,ccache->cc,&cursor);
+
+	if (*errstr) {
+		php_krb5_display_error(ccache->ctx, retval, errstr TSRMLS_CC);
+		array_init(return_value);
+	}
+}
+#undef ENCSTRMAX
+/* }}} */
+
+/* {{{ proto bool KRB5CCache::renew( )
+   Renew default TGT and purge other tickets from cache, return FALSE on failure  */
+PHP_METHOD(KRB5CCache, renew)
+{
+	krb5_ccache_object *ccache = KRB5_THIS_CCACHE;
+	krb5_error_code retval = 0;
+	char *errstr = "";
+	long endtime, renew_until;
+	krb5_timestamp now;
+	krb5_principal princ;
+	int have_princ = 0;
+	krb5_creds creds;
+	int have_creds = 0;
+
+	if (zend_parse_parameters_none() == FAILURE) {
+		zend_throw_exception(NULL, "Failed to parse arglist", 0 TSRMLS_CC);
+		RETURN_FALSE;
+	}
+
+    do {
+	if ((retval = php_krb5_get_tgt_expire(ccache, &endtime, &renew_until TSRMLS_CC))) {
+		errstr = "Failed to get renew_until () (%s)";
+		break;
+	}
+
+	if ((retval = krb5_timeofday(ccache->ctx, &now))) {
+		errstr = "Failed to read clock in renew() (%s)";
+		break;
+	}
+
+	if (now > renew_until) {
+		/* ticket is not renewable, but... */
+		if (now >= endtime) retval = -1; /* ...is it still useful? */
+		break;
+	}
+
+	memset(&princ, 0, sizeof(princ));
+	if ((retval = krb5_cc_get_principal(ccache->ctx, ccache->cc, &princ))) {
+		errstr = "Failed to get principal from cache (%s)";
+		break;
+	}
+	have_princ = 1;
+
+	memset(&creds, 0, sizeof(creds));
+	if ((retval = krb5_get_renewed_creds(ccache->ctx, &creds, princ, ccache->cc, \
NULL))) { +		errstr = "Failed to renew TGT in cache (%s)";
+		break;
+	}
+	have_creds = 1;
+
+	if ((retval = krb5_cc_initialize(ccache->ctx, ccache->cc, princ))) {
+		errstr = "Failed to reinitialize ccache after TGT renewal (%s)";
+		break;
+	}
+
+	if((retval = krb5_cc_store_cred(ccache->ctx, ccache->cc, &creds))) {
+		errstr = "Failed to store renewed TGT in ccache (%s)";
+		break;
+	}
+    } while (0);
+
+	if (have_princ) krb5_free_principal(ccache->ctx, princ);
+	if (have_creds) krb5_free_cred_contents(ccache->ctx, &creds);
+
+	if (retval) {
+		if (*errstr) {
+			php_krb5_display_error(ccache->ctx, retval, errstr TSRMLS_CC);
+		}
+		RETURN_FALSE;
+	}
+
+	/* otherwise */
+	RETURN_TRUE;
+}
+/* }}} */
+
+/* bottom of file */

Copied: pecl/krb5/tags/krb5-1.1.0/trunk/negotiate_auth.c (from rev 339675, \
pecl/krb5/trunk/negotiate_auth.c) \
                ===================================================================
--- pecl/krb5/tags/krb5-1.1.0/trunk/negotiate_auth.c	                        (rev 0)
+++ pecl/krb5/tags/krb5-1.1.0/trunk/negotiate_auth.c	2016-07-16 14:46:31 UTC (rev \
339676) @@ -0,0 +1,466 @@
+/**
+* Copyright (c) 2008 Moritz Bechler
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+* THE SOFTWARE.
+**/
+
+#include "php_krb5.h"
+#include "php_krb5_gssapi.h"
+#include "compat.h"
+#include "SAPI.h"
+#include "ext/standard/base64.h"
+#include <math.h>
+#include <netdb.h>
+#include <sys/socket.h>
+
+/* Class definition */
+zend_object_handlers krb5_negotiate_auth_handlers;
+
+zend_class_entry *krb5_ce_negotiate_auth;
+typedef struct _krb5_negotiate_auth_object {
+#if PHP_MAJOR_VERSION < 7
+	zend_object std;
+#endif
+	gss_name_t servname;
+	gss_name_t authed_user;
+	gss_cred_id_t delegated;
+#if PHP_MAJOR_VERSION >= 7
+	zend_object std;
+#endif
+} krb5_negotiate_auth_object;
+
+
+#if PHP_MAJOR_VERSION < 7
+static void php_krb5_negotiate_auth_object_dtor(void *obj, zend_object_handle handle \
TSRMLS_DC); +zend_object_value php_krb5_negotiate_auth_object_new(zend_class_entry \
*ce TSRMLS_DC); +#else
+static void php_krb5_negotiate_auth_object_free(zend_object *obj TSRMLS_DC);
+zend_object *php_krb5_ticket_object_new(zend_class_entry *ce TSRMLS_DC);
+#endif
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_KRB5NegotiateAuth_none, 0, 0, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_KRB5NegotiateAuth__construct, 0, 0, 1)
+	ZEND_ARG_INFO(0, keytab)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_KRB5NegotiateAuth_getDelegatedCredentials, 0, 0, 1)
+	ZEND_ARG_OBJ_INFO(0, ccache, KRB5CCache, 0)
+ZEND_END_ARG_INFO()
+
+PHP_METHOD(KRB5NegotiateAuth, __construct);
+PHP_METHOD(KRB5NegotiateAuth, doAuthentication);
+PHP_METHOD(KRB5NegotiateAuth, getDelegatedCredentials);
+PHP_METHOD(KRB5NegotiateAuth, getAuthenticatedUser);
+
+static zend_function_entry krb5_negotiate_auth_functions[] = {
+	PHP_ME(KRB5NegotiateAuth, __construct,             \
arginfo_KRB5NegotiateAuth__construct,              ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) \
+	PHP_ME(KRB5NegotiateAuth, doAuthentication,        arginfo_KRB5NegotiateAuth_none,  \
ZEND_ACC_PUBLIC) +	PHP_ME(KRB5NegotiateAuth, getDelegatedCredentials, \
arginfo_KRB5NegotiateAuth_getDelegatedCredentials, ZEND_ACC_PUBLIC) \
+	PHP_ME(KRB5NegotiateAuth, getAuthenticatedUser,    arginfo_KRB5NegotiateAuth_none,  \
ZEND_ACC_PUBLIC) +	PHP_FE_END
+};
+
+
+/** Registration **/
+/* {{{ */
+#if PHP_MAJOR_VERSION < 7
+static void php_krb5_negotiate_auth_object_dtor(void *obj, zend_object_handle handle \
TSRMLS_DC) +{
+	krb5_negotiate_auth_object *object = (krb5_negotiate_auth_object*)obj;
+
+	OBJECT_STD_DTOR(object->std);
+
+	if ( object->servname ) {
+		free(object->servname);
+	}
+	efree(object);
+}
+#else
+static void php_krb5_negotiate_auth_object_free(zend_object *obj TSRMLS_DC)
+{
+	krb5_negotiate_auth_object *object = (krb5_negotiate_auth_object*)((char *)obj - \
XtOffsetOf(krb5_negotiate_auth_object, std)); +
+	if ( object->servname ) {
+		free(object->servname);
+	}
+	zend_object_std_dtor(obj);
+}
+#endif
+/* }}} */
+
+
+static void setup_negotiate_auth(krb5_negotiate_auth_object *object TSRMLS_DC) {
+	object->authed_user = GSS_C_NO_NAME;
+	object->servname = GSS_C_NO_NAME;
+	object->delegated = GSS_C_NO_CREDENTIAL;
+}
+
+/* {{{ */
+#if PHP_MAJOR_VERSION < 7
+zend_object_value php_krb5_negotiate_auth_object_new(zend_class_entry *ce TSRMLS_DC)
+{
+	zend_object_value retval;
+	krb5_negotiate_auth_object *object;
+	object = emalloc(sizeof(krb5_negotiate_auth_object));
+
+	setup_negotiate_auth(object TSRMLS_CC);
+
+	INIT_STD_OBJECT(object->std, ce);
+
+#if PHP_VERSION_ID < 50399
+	zend_hash_copy(object->std.properties, &ce->default_properties,
+	        		(copy_ctor_func_t) zval_add_ref, NULL,
+					sizeof(zval*));
+#else
+	object_properties_init(&(object->std), ce);
+#endif
+
+	retval.handle = zend_objects_store_put(object, php_krb5_negotiate_auth_object_dtor, \
NULL, NULL TSRMLS_CC); +
+	retval.handlers = &krb5_negotiate_auth_handlers;
+	return retval;
+}
+#else
+zend_object *php_krb5_negotiate_auth_object_new(zend_class_entry *ce TSRMLS_DC)
+{
+	krb5_negotiate_auth_object *object;
+	object = ecalloc(1, sizeof(krb5_negotiate_auth_object) + \
zend_object_properties_size(ce)); +
+	setup_negotiate_auth(object TSRMLS_CC);
+
+	zend_object_std_init(&object->std, ce TSRMLS_CC);
+	object_properties_init(&object->std, ce);
+	object->std.handlers = &krb5_negotiate_auth_handlers;
+	return &object->std;
+}
+#endif
+/* }}} */
+
+/* {{{ */
+int php_krb5_negotiate_auth_register_classes(TSRMLS_D) {
+	zend_class_entry negotiate_auth;
+
+	INIT_CLASS_ENTRY(negotiate_auth, "KRB5NegotiateAuth", \
krb5_negotiate_auth_functions); +	krb5_ce_negotiate_auth = \
zend_register_internal_class(&negotiate_auth TSRMLS_CC); \
+	krb5_ce_negotiate_auth->create_object = php_krb5_negotiate_auth_object_new; \
+	memcpy(&krb5_negotiate_auth_handlers, zend_get_std_object_handlers(), \
sizeof(zend_object_handlers)); +#if PHP_MAJOR_VERSION >= 7
+	krb5_negotiate_auth_handlers.offset = XtOffsetOf(krb5_negotiate_auth_object, std);
+	krb5_negotiate_auth_handlers.free_obj = php_krb5_negotiate_auth_object_free;
+#endif
+
+	return SUCCESS;
+}
+/* }}} */
+
+
+/** KRB5NegotiateAuth Methods **/
+/* {{{ proto bool KRB5NegotiateAuth::__construct( string $keytab )
+   Initialize KRB5NegotitateAuth object with a keytab to use  */
+PHP_METHOD(KRB5NegotiateAuth, __construct)
+{
+	gss_buffer_desc nametmp;
+	OM_uint32 status, minor_status;
+	krb5_negotiate_auth_object *object;
+	char *keytab;
+	strsize_t keytab_len = 0;
+
+	KRB5_SET_ERROR_HANDLING(EH_THROW);
+	if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, ARG_PATH, &keytab, &keytab_len) \
== FAILURE) { +		RETURN_FALSE;
+	}
+	KRB5_SET_ERROR_HANDLING(EH_NORMAL);
+
+	object = KRB5_THIS_NEGOTIATE_AUTH;
+
+	/* lookup server's FQDN */
+	zval *server, *server_name;
+	server = zend_compat_hash_find(&EG(symbol_table), "_SERVER", sizeof("_SERVER"));
+	if ( server != NULL ) {
+		server_name = zend_compat_hash_find(HASH_OF(server), "SERVER_NAME", \
sizeof("SERVER_NAME")); +		if ( server_name != NULL ) {
+			char *hostname = Z_STRVAL_P(server_name);
+			struct hostent* host = gethostbyname(hostname);
+
+			if(!host) {
+				zend_throw_exception(NULL, "Failed to get server FQDN - Lookup failure", 0 \
TSRMLS_CC); +				return;
+			}
+
+			nametmp.length = strlen(host->h_name) + 6;
+			nametmp.value = emalloc(sizeof(char)*nametmp.length);
+			snprintf(nametmp.value, nametmp.length, "HTTP@%s",host->h_name);
+
+			status = gss_import_name(&minor_status, &nametmp,
+							GSS_C_NT_HOSTBASED_SERVICE, &object->servname);
+
+			if(GSS_ERROR(status)) {
+				php_krb5_gssapi_handle_error(status, minor_status TSRMLS_CC);
+				zend_throw_exception(NULL, "Could not parse server name", 0 TSRMLS_CC);
+				return;
+			}
+
+			efree(nametmp.value);
+		} else {
+			zend_throw_exception(NULL, "Failed to get server FQDN", 0 TSRMLS_CC);
+			return;
+		}
+	}
+
+	if(krb5_gss_register_acceptor_identity(keytab) != GSS_S_COMPLETE) {
+		zend_throw_exception(NULL, "Failed to use credential cache", 0 TSRMLS_CC);
+		return;
+	}
+} /* }}} */
+
+/* {{{ proto bool KRB5NegotiateAuth::doAuthentication(  )
+   Performs Negotiate/GSSAPI authentication  */
+PHP_METHOD(KRB5NegotiateAuth, doAuthentication)
+{
+	zend_string *token = NULL;
+	krb5_negotiate_auth_object *object;
+
+	OM_uint32 status = 0;
+	OM_uint32 minor_status = 0;
+	OM_uint32 flags;
+	gss_ctx_id_t gss_context = GSS_C_NO_CONTEXT;
+	gss_buffer_desc input_token;
+	gss_buffer_desc output_token;
+	gss_cred_id_t server_creds = GSS_C_NO_CREDENTIAL;
+
+	if (zend_parse_parameters_none() == FAILURE) {
+		RETURN_FALSE;
+	}
+
+	object = KRB5_THIS_NEGOTIATE_AUTH;
+
+	if(!object) {
+		RETURN_FALSE;
+	}
+
+
+	/* get authentication data */
+	zval *auth_header = NULL;
+
+#if PHP_MAJOR_VERSION < 7
+	HashTable* server_vars = PG(http_globals)[TRACK_VARS_SERVER] != NULL ? \
PG(http_globals)[TRACK_VARS_SERVER]->value.ht : NULL; +#else
+	HashTable* server_vars = Z_ARRVAL(PG(http_globals)[TRACK_VARS_SERVER]);
+#endif
+
+	if(server_vars && (auth_header = zend_compat_hash_find(server_vars, \
"HTTP_AUTHORIZATION", sizeof("HTTP_AUTHORIZATION"))) != NULL) { +
+		if(!strncasecmp(Z_STRVAL_P(auth_header), "negotiate", 9) == 0) {
+ 			// user agent did not provide negotiate authentication data
+ 			RETURN_FALSE;
+ 		}
+
+		if(Z_STRLEN_P(auth_header) < 11) {
+ 			// user agent gave negotiate header but no data
+ 			zend_throw_exception(NULL, "Invalid negotiate authentication data given", 0 \
TSRMLS_CC); + 			return;
+ 		}
+#if PHP_MAJOR_VERSION < 7
+		int len = 0;
+		char *str = (char*) php_base64_decode_ex((unsigned char*) \
Z_STRVAL_P(auth_header)+10, Z_STRLEN_P(auth_header) - 10, &len, 1); +		token = \
zend_string_init(str, len, 0); +		efree(str);
+#else
+		token = php_base64_decode_ex((unsigned char*) Z_STRVAL_P(auth_header)+10, \
Z_STRLEN_P(auth_header) - 10, 1); +#endif
+	} else {
+		// No authentication data given by the user agent
+		sapi_header_line ctr = {0};
+
+		ctr.line = "WWW-Authenticate: Negotiate";
+		ctr.line_len = strlen("WWW-Authenticate: Negotiate");
+		ctr.response_code = 401;
+		sapi_header_op(SAPI_HEADER_ADD, &ctr TSRMLS_CC);
+		RETURN_FALSE;
+	}
+
+	if(!token) {
+        	zend_throw_exception(NULL, "Failed to decode token data", 0 TSRMLS_CC);
+		return;
+	}
+
+	status = gss_acquire_cred(&minor_status,
+			object->servname,
+			0,
+			GSS_C_NO_OID_SET,
+			GSS_C_ACCEPT,
+			&server_creds,
+			NULL,
+			NULL);
+
+	if(GSS_ERROR(status)) {
+		zend_string_release(token);
+		php_krb5_gssapi_handle_error(status, minor_status TSRMLS_CC);
+		zend_throw_exception(NULL, "Error while obtaining server credentials", status \
TSRMLS_CC); +		RETURN_FALSE;
+	}
+	minor_status = 0;
+
+	input_token.length = token->len;
+	input_token.value = token->val;
+
+	status = gss_accept_sec_context(   &minor_status,
+                                       &gss_context,
+                                       server_creds,
+                                       &input_token,
+                                       GSS_C_NO_CHANNEL_BINDINGS,
+                                       &object->authed_user,
+                                       NULL,
+                                       &output_token,
+                                       &flags,
+                                       NULL,
+                                       &object->delegated);
+
+
+	if(!(flags & GSS_C_DELEG_FLAG)) {
+		object->delegated = GSS_C_NO_CREDENTIAL;
+	}
+
+	zend_string_release(token);
+
+	if(GSS_ERROR(status)) {
+		php_krb5_gssapi_handle_error(status, minor_status TSRMLS_CC);
+		zend_throw_exception(NULL, "Error while accepting security context", status \
TSRMLS_CC); +		RETURN_FALSE;
+	}
+
+	if(gss_context != GSS_C_NO_CONTEXT) {
+		gss_delete_sec_context(&minor_status, &gss_context, GSS_C_NO_BUFFER);
+	}
+
+	if(output_token.length > 0) {
+
+#if PHP_MAJOR_VERSION < 7
+		int len = 0;
+		char *str = (char*) php_base64_encode(output_token.value, output_token.length, \
&len); +		zend_string *encoded = zend_string_init(str, len, 0);
+		efree(str);
+#else
+		zend_string *encoded = php_base64_encode(output_token.value, output_token.length);
+#endif
+
+		sapi_header_line ctr = {0};
+
+		ctr.line = emalloc(sizeof("WWW-Authenticate: ")+encoded->len);
+		strcpy(ctr.line, "WWW-Authenticate: ");
+		strcpy(ctr.line + strlen("WWW-Authenticate: "), encoded->val);
+		ctr.response_code = 200;
+		sapi_header_op(SAPI_HEADER_ADD, &ctr TSRMLS_CC);
+		zend_string_release(encoded);
+
+		efree(ctr.line);
+		gss_release_buffer(&minor_status, &output_token);
+	}
+	RETURN_TRUE;
+} /* }}} */
+
+/* {{{ proto string KRB5NegotiateAuth::getAuthenticatedUser(  )
+   Gets the principal name of the authenticated user  */
+PHP_METHOD(KRB5NegotiateAuth, getAuthenticatedUser)
+{
+	OM_uint32 status, minor_status;
+	krb5_negotiate_auth_object *object;
+
+	if (zend_parse_parameters_none() == FAILURE) {
+		RETURN_FALSE;
+	}
+	object = KRB5_THIS_NEGOTIATE_AUTH;
+
+	if(!object || !object->authed_user || object->authed_user == GSS_C_NO_NAME) {
+		RETURN_FALSE;
+	}
+
+	gss_buffer_desc username_tmp;
+	status = gss_display_name(&minor_status, object->authed_user, &username_tmp, NULL);
+
+	if(GSS_ERROR(status)) {
+		php_krb5_gssapi_handle_error(status, minor_status TSRMLS_CC);
+		RETURN_FALSE;
+	}
+
+	_ZVAL_STRINGL(return_value, username_tmp.value, username_tmp.length);
+	gss_release_buffer(&minor_status, &username_tmp);
+} /* }}} */
+
+/* {{{ proto void KRB5NegotiateAuth::getDelegatedCredentials( KRB5CCache $ccache )
+   Fills a credential cache with the delegated credentials  */
+PHP_METHOD(KRB5NegotiateAuth, getDelegatedCredentials)
+{
+	OM_uint32 status, minor_status;
+	krb5_negotiate_auth_object *object;
+	zval *zticket;
+	krb5_ccache_object *ticket;
+	krb5_error_code retval = 0;
+	krb5_principal princ;
+
+	object = KRB5_THIS_NEGOTIATE_AUTH;
+
+	if(object->delegated == GSS_C_NO_CREDENTIAL) {
+		zend_throw_exception(NULL, "No delegated credentials available", 0 TSRMLS_CC);
+		return;
+	}
+
+	if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &zticket, krb5_ce_ccache) \
== FAILURE) { +		return;
+	}
+
+	ticket = KRB5_CCACHE(zticket);
+	if(!ticket) {
+		zend_throw_exception(NULL, "Invalid KRB5CCache object given", 0 TSRMLS_CC);
+		return;
+	}
+
+
+	/* use principal name for ccache initialization */
+	gss_buffer_desc nametmp;
+	status = gss_display_name(&minor_status, object->authed_user, &nametmp, NULL);
+	if(GSS_ERROR(status)) {
+		php_krb5_gssapi_handle_error(status, minor_status TSRMLS_CC);
+		return;
+	}
+
+	if((retval = krb5_parse_name(ticket->ctx, nametmp.value, &princ))) {
+		php_krb5_display_error(ticket->ctx, retval,  "Failed to parse principal name (%s)" \
TSRMLS_CC); +		return;
+	}
+
+	if((retval = krb5_cc_initialize(ticket->ctx, ticket->cc, princ))) {
+		krb5_free_principal(ticket->ctx,princ);
+		php_krb5_display_error(ticket->ctx, retval,  "Failed to initialize credential \
cache (%s)" TSRMLS_CC); +		return;
+	}
+
+	/* copy credentials to ccache */
+	status = gss_krb5_copy_ccache(&minor_status, object->delegated, ticket->cc);
+
+	if(GSS_ERROR(status)) {
+		php_krb5_gssapi_handle_error(status, minor_status TSRMLS_CC);
+		zend_throw_exception(NULL, "Failure while imporing delegated ticket", 0 \
TSRMLS_CC); +		return;
+	}
+
+} /* }}} */
+

Copied: pecl/krb5/tags/krb5-1.1.0/trunk/package.xml (from rev 339675, \
pecl/krb5/trunk/package.xml) \
=================================================================== (Binary files \
differ)

Copied: pecl/krb5/tags/krb5-1.1.0/trunk/php_krb5.h (from rev 339675, \
pecl/krb5/trunk/php_krb5.h) \
                ===================================================================
--- pecl/krb5/tags/krb5-1.1.0/trunk/php_krb5.h	                        (rev 0)
+++ pecl/krb5/tags/krb5-1.1.0/trunk/php_krb5.h	2016-07-16 14:46:31 UTC (rev 339676)
@@ -0,0 +1,91 @@
+/**
+* Copyright (c) 2008 Moritz Bechler
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+* THE SOFTWARE.
+**/
+
+#ifndef PHP_KRB5_H
+#define PHP_KRB5_H
+
+#ifdef ZTS
+#include "TSRM.h"
+#endif
+
+#include "php.h"
+#include "Zend/zend_exceptions.h"
+#include "php_krb5_gssapi.h"
+
+#ifdef HAVE_KADM5
+#define KADM5_API_VERSION 2
+#endif
+
+#define PHP_SUCCESS SUCCESS
+
+#define KRB5_PRIVATE 1
+
+#include <krb5.h>
+#include <gssapi/gssapi.h>
+#include <gssapi/gssapi_krb5.h>
+
+#define PHP_KRB5_EXT_NAME "krb5"
+#define PHP_KRB5_VERSION "1.1.0"
+
+
+extern zend_module_entry krb5_module_entry;
+#define phpext_krb5_ptr &krb5_module_entry
+
+#ifdef PHP_WIN32
+#define PHP_KRB5_API __dllspec(dllexport)
+#else
+#define PHP_KRB5_API
+#endif
+
+
+PHP_MINIT_FUNCTION(krb5);
+PHP_MSHUTDOWN_FUNCTION(krb5);
+PHP_MINFO_FUNCTION(krb5);
+
+zend_class_entry *krb5_ce_ccache;
+
+typedef struct _krb5_ccache_object {
+#if PHP_MAJOR_VERSION < 7
+	zend_object std;
+#endif
+	krb5_context ctx;
+	krb5_ccache cc;
+	char *keytab;
+#if PHP_MAJOR_VERSION >= 7
+	zend_object std;
+#endif
+} krb5_ccache_object;
+
+krb5_error_code php_krb5_display_error(krb5_context ctx, krb5_error_code code, char* \
str TSRMLS_DC); +
+
+/* KRB5NegotiateAuth Object */
+int php_krb5_negotiate_auth_register_classes(TSRMLS_D);
+
+/* KADM5 glue */
+#ifdef HAVE_KADM5
+int php_krb5_kadm5_register_classes(TSRMLS_D);
+#endif
+
+
+
+#endif /* PHP_KRB5_H */

Copied: pecl/krb5/tags/krb5-1.1.0/trunk/php_krb5_gssapi.h (from rev 339675, \
pecl/krb5/trunk/php_krb5_gssapi.h) \
                ===================================================================
--- pecl/krb5/tags/krb5-1.1.0/trunk/php_krb5_gssapi.h	                        (rev 0)
+++ pecl/krb5/tags/krb5-1.1.0/trunk/php_krb5_gssapi.h	2016-07-16 14:46:31 UTC (rev \
339676) @@ -0,0 +1,43 @@
+/**
+* Copyright (c) 2008 Moritz Bechler
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+* THE SOFTWARE.
+**/
+
+#ifndef PHP_KRB5_GSSAPI_H
+#define PHP_KRB5_GSSAPI_H
+
+#include <gssapi/gssapi.h>
+
+void php_krb5_gssapi_handle_error(OM_uint32 major, OM_uint32 minor TSRMLS_DC);
+int php_krb5_gssapi_register_classes(TSRMLS_D);
+int php_krb5_gssapi_shutdown(TSRMLS_D);
+
+
+#if PHP_MAJOR_VERSION < 7
+extern void php_krb5_gssapi_context_object_dtor(void *obj, zend_object_handle handle \
TSRMLS_DC); +zend_object_value php_krb5_gssapi_context_object_new(zend_class_entry \
*ce TSRMLS_DC); +#else
+extern void php_krb5_gssapi_context_object_free(zend_object *obj TSRMLS_DC);
+zend_object *php_krb5_gssapi_context_object_new(zend_class_entry *ce TSRMLS_DC);
+#endif
+
+
+#endif /* PHP_KRB5_GSSAPI_H */
+

Copied: pecl/krb5/tags/krb5-1.1.0/trunk/php_krb5_kadm.h (from rev 339675, \
pecl/krb5/trunk/php_krb5_kadm.h) \
                ===================================================================
--- pecl/krb5/tags/krb5-1.1.0/trunk/php_krb5_kadm.h	                        (rev 0)
+++ pecl/krb5/tags/krb5-1.1.0/trunk/php_krb5_kadm.h	2016-07-16 14:46:31 UTC (rev \
339676) @@ -0,0 +1,202 @@
+/**
+* Copyright (c) 2008 Moritz Bechler
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+* THE SOFTWARE.
+**/
+
+#ifndef PHP_KRB5_KADM_H
+#define PHP_KRB5_KADM_H
+
+#include "config.h"
+
+/* will be used in gssrpc/rpc_msg.h enum accept_stat */
+#undef  SUCCESS
+#define SUCCESS KRB5_SUCCESS
+#include <kadm5/admin.h>
+#undef  SUCCESS
+/* default value in PHP and Kerberos */
+#define SUCCESS 0
+
+/* KADM5 Object */
+	zend_class_entry *krb5_ce_kadm5;
+
+	typedef struct _krb5_kadm5_object {
+#if PHP_MAJOR_VERSION < 7
+		zend_object std;
+#endif
+		void *handle;
+		krb5_context ctx;
+		kadm5_config_params config;
+#if PHP_MAJOR_VERSION >= 7
+		zend_object std;
+#endif
+	} krb5_kadm5_object;
+
+	void php_krb5_free_kadm5_object(krb5_kadm5_object *obj);
+
+	/* Kerberos Admin functions */
+	PHP_METHOD(KADM5, __construct);
+	PHP_METHOD(KADM5, getPrincipal);
+	PHP_METHOD(KADM5, getPrincipals);
+	PHP_METHOD(KADM5, createPrincipal);
+	PHP_METHOD(KADM5, getPolicy);
+	PHP_METHOD(KADM5, createPolicy);
+	PHP_METHOD(KADM5, getPolicies);
+
+
+
+	/* KADM5Principal Object */
+	zend_class_entry *krb5_ce_kadm5_principal;
+
+	typedef struct _krb5_kadm5_principal_object {
+#if PHP_MAJOR_VERSION < 7
+		zend_object std;
+#endif
+		int loaded;
+		long int update_mask;
+		kadm5_principal_ent_rec data;
+		krb5_kadm5_object *conn;
+#if PHP_MAJOR_VERSION >= 7
+		zend_object std;
+#endif
+	} krb5_kadm5_principal_object;
+
+	int php_krb5_register_kadm5_principal(TSRMLS_D);
+
+#if PHP_MAJOR_VERSION < 7
+	zend_object_value php_krb5_kadm5_principal_object_new(zend_class_entry *ce \
TSRMLS_DC); +#else
+	zend_object* php_krb5_kadm5_principal_object_new(zend_class_entry *ce TSRMLS_DC);
+#endif
+
+	PHP_METHOD(KADM5Principal, __construct);
+	PHP_METHOD(KADM5Principal, load);
+	PHP_METHOD(KADM5Principal, save);
+	PHP_METHOD(KADM5Principal, delete);
+	PHP_METHOD(KADM5Principal, rename);
+
+	PHP_METHOD(KADM5Principal, changePassword);
+
+	PHP_METHOD(KADM5Principal, getPropertyArray);
+
+	PHP_METHOD(KADM5Principal, getName);
+	PHP_METHOD(KADM5Principal, getExpiryTime);
+	PHP_METHOD(KADM5Principal, setExpiryTime);
+	PHP_METHOD(KADM5Principal, getLastPasswordChange);
+	PHP_METHOD(KADM5Principal, getPasswordExpiryTime);
+	PHP_METHOD(KADM5Principal, setPasswordExpiryTime);
+	PHP_METHOD(KADM5Principal, getMaxTicketLifetime);
+	PHP_METHOD(KADM5Principal, setMaxTicketLifetime);
+	PHP_METHOD(KADM5Principal, getLastModifier);
+	PHP_METHOD(KADM5Principal, getLastModificationDate);
+	PHP_METHOD(KADM5Principal, getKeyVNO);
+	PHP_METHOD(KADM5Principal, setKeyVNO);
+	PHP_METHOD(KADM5Principal, getMasterKeyVNO);
+	PHP_METHOD(KADM5Principal, setAttributes);
+	PHP_METHOD(KADM5Principal, getAttributes);
+	PHP_METHOD(KADM5Principal, getAuxAttributes);
+	PHP_METHOD(KADM5Principal, getPolicy);
+	PHP_METHOD(KADM5Principal, setPolicy);
+	PHP_METHOD(KADM5Principal, clearPolicy);
+	PHP_METHOD(KADM5Principal, getLastSuccess);
+	PHP_METHOD(KADM5Principal, getLastFailed);
+	PHP_METHOD(KADM5Principal, getFailedAuthCount);
+	PHP_METHOD(KADM5Principal, resetFailedAuthCount);
+	PHP_METHOD(KADM5Principal, getMaxRenewableLifetime);
+	PHP_METHOD(KADM5Principal, setMaxRenewableLifetime);
+	PHP_METHOD(KADM5Principal, getTLData);
+	PHP_METHOD(KADM5Principal, setTLData);
+
+
+
+	/* KADM5Policy Object */
+	zend_class_entry *krb5_ce_kadm5_policy;
+
+	typedef struct _krb5_kadm5_policy_object {
+#if PHP_MAJOR_VERSION < 7
+		zend_object std;
+#endif
+		char *policy;
+		long int update_mask;
+		kadm5_policy_ent_rec data;
+		krb5_kadm5_object *conn;
+#if PHP_MAJOR_VERSION >= 7
+		zend_object std;
+#endif
+	} krb5_kadm5_policy_object;
+
+
+	int php_krb5_register_kadm5_policy(TSRMLS_D);
+
+#if PHP_MAJOR_VERSION < 7
+	zend_object_value php_krb5_kadm5_policy_object_new(zend_class_entry *ce TSRMLS_DC);
+#else
+	zend_object* php_krb5_kadm5_policy_object_new(zend_class_entry *ce TSRMLS_DC);
+#endif
+
+	PHP_METHOD(KADM5Policy, __construct);
+	PHP_METHOD(KADM5Policy, __destruct);
+	PHP_METHOD(KADM5Policy, load);
+	PHP_METHOD(KADM5Policy, save);
+	PHP_METHOD(KADM5Policy, delete);
+
+	PHP_METHOD(KADM5Policy, getPropertyArray);
+
+	PHP_METHOD(KADM5Policy, getName);
+	PHP_METHOD(KADM5Policy, getMinPasswordLife);
+	PHP_METHOD(KADM5Policy, setMinPasswordLife);
+	PHP_METHOD(KADM5Policy, getMaxPasswordLife);
+	PHP_METHOD(KADM5Policy, setMaxPasswordLife);
+	PHP_METHOD(KADM5Policy, getMinPasswordLength);
+	PHP_METHOD(KADM5Policy, setMinPasswordLength);
+	PHP_METHOD(KADM5Policy, getMinPasswordClasses);
+	PHP_METHOD(KADM5Policy, setMinPasswordClasses);
+	PHP_METHOD(KADM5Policy, getHistoryNum);
+	PHP_METHOD(KADM5Policy, setHistoryNum);
+	PHP_METHOD(KADM5Policy, getReferenceCount);
+
+
+	/* KADM5TLData Object */
+	zend_class_entry *krb5_ce_kadm5_tldata;
+
+	typedef struct _krb5_kadm5_tldata_object {
+#if PHP_MAJOR_VERSION < 7
+		zend_object std;
+#endif
+		krb5_tl_data data;
+#if PHP_MAJOR_VERSION >= 7
+		zend_object std;
+#endif
+	} krb5_kadm5_tldata_object;
+
+	int php_krb5_register_kadm5_tldata(TSRMLS_D);
+#if PHP_MAJOR_VERSION < 7
+	zend_object_value php_krb5_kadm5_tldata_object_new(zend_class_entry *ce TSRMLS_DC);
+#else
+	zend_object* php_krb5_kadm5_tldata_object_new(zend_class_entry *ce TSRMLS_DC);
+#endif
+
+	PHP_METHOD(KADM5TLData, __construct);
+	PHP_METHOD(KADM5TLData, getType);
+	PHP_METHOD(KADM5TLData, getData);
+
+	void php_krb5_kadm5_tldata_to_array(zval *array, krb5_tl_data *data, krb5_int16 num \
TSRMLS_DC); +	krb5_tl_data* php_krb5_kadm5_tldata_from_array(zval *array, krb5_int16* \
count TSRMLS_DC); +	void php_krb5_kadm5_tldata_free(krb5_tl_data *data, krb5_int16 \
num TSRMLS_DC); +#endif

Copied: pecl/krb5/tags/krb5-1.1.0/trunk/tests/001.phpt (from rev 339675, \
pecl/krb5/trunk/tests/001.phpt) \
                ===================================================================
--- pecl/krb5/tags/krb5-1.1.0/trunk/tests/001.phpt	                        (rev 0)
+++ pecl/krb5/tags/krb5-1.1.0/trunk/tests/001.phpt	2016-07-16 14:46:31 UTC (rev \
339676) @@ -0,0 +1,47 @@
+--TEST--
+Testing for usable ticket acqusition
+--SKIPIF--
+<?php
+if(!file_exists(dirname(__FILE__) . '/config.php')) { echo "skip config missing"; \
return; } +if(!include(dirname(__FILE__) . '/config.php')) return;
+?>
+--FILE--
+<?php
+include(dirname(__FILE__) . '/config.php');
+$ccache = new KRB5CCache();
+if($use_config) {
+	$ccache->setConfig(dirname(__FILE__) . '/krb5.ini');
+}
+
+var_dump(count($ccache->getEntries()));
+$ccache->initPassword($client_principal, $client_password, array('tkt_life' => \
360)); +var_dump(count($ccache->getEntries())); // should contain a TGT
+list($tgt) = $ccache->getEntries();
+var_dump($ccache->isValid());
+var_dump($ccache->isValid(720));
+$ccache->save(dirname(__FILE__) . '/ccache.tmp');
+$ccache->save('FILE:' . dirname(__FILE__) . '/ccache2.tmp');
+var_dump(file_exists(dirname(__FILE__) . '/ccache.tmp'));
+var_dump(file_exists(dirname(__FILE__) . '/ccache2.tmp'));
+@unlink(dirname(__FILE__) . '/ccache2.tmp');
+$ccache2 = new KRB5CCache();
+$ccache2->open('FILE:' . dirname(__FILE__) . '/ccache.tmp');
+var_dump(in_array($tgt,$ccache2->getEntries()));
+@unlink(dirname(__FILE__) . '/ccache.tmp');
+
+$ccache3 = new KRB5CCache();
+$ccache3->initKeytab($server_principal, $server_keytab);
+var_dump(count($ccache->getEntries()));
+var_dump($ccache->isValid());
+
+?>
+--EXPECTF--
+int(0)
+int(1)
+bool(true)
+bool(false)
+bool(true)
+bool(true)
+bool(true)
+int(1)
+bool(true)

Copied: pecl/krb5/tags/krb5-1.1.0/trunk/tests/002.phpt (from rev 339675, \
pecl/krb5/trunk/tests/002.phpt) \
                ===================================================================
--- pecl/krb5/tags/krb5-1.1.0/trunk/tests/002.phpt	                        (rev 0)
+++ pecl/krb5/tags/krb5-1.1.0/trunk/tests/002.phpt	2016-07-16 14:46:31 UTC (rev \
339676) @@ -0,0 +1,57 @@
+--TEST--
+Testing for basic GSSAPI context establishment
+--SKIPIF--
+<?php
+if(!file_exists(dirname(__FILE__) . '/config.php')) { echo "skip config missing"; \
return; } +if(!include(dirname(__FILE__) . '/config.php')) return;
+?>
+--FILE--
+<?php
+include(dirname(__FILE__) . '/config.php');
+$client = new KRB5CCache();
+if($use_config) {
+	$client->setConfig(dirname(__FILE__) . '/krb5.ini');
+}
+
+$client->initPassword($client_principal, $client_password, array('tkt_life' => \
360)); +
+$server = new KRB5CCache();
+if($use_config) {
+        $server->setConfig(dirname(__FILE__) . '/krb5.ini');
+}
+
+$server->initKeytab($server_principal, $server_keytab);
+
+$cgssapi = new GSSAPIContext();
+$sgssapi = new GSSAPIContext();
+
+$orig_ktname = getenv("KRB5_KTNAME");
+$orig_ccname = getenv("KRB5CCNAME");
+
+$cgssapi->acquireCredentials($client, $client_principal, GSS_C_INITIATE);
+$sgssapi->acquireCredentials($server);
+
+$client_info = $cgssapi->inquireCredentials();
+$server_info = $sgssapi->inquireCredentials();
+
+var_dump($orig_ktname === getenv("KRB5_KTNAME"));
+var_dump($orig_ccname === getenv("KRB5CCNAME"));
+
+var_dump($client->isValid($client_info['lifetime_remain'] - 300));
+var_dump($server->isValid($server_info['lifetime_remain'] - 300));
+
+$token = '';
+
+var_dump($cgssapi->initSecContext($server_principal, null, null, null, $token));
+var_dump($sgssapi->acceptSecContext($token));
+
+
+
+?>
+--EXPECTF--
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)

Copied: pecl/krb5/tags/krb5-1.1.0/trunk/tests/003.phpt (from rev 339675, \
pecl/krb5/trunk/tests/003.phpt) \
                ===================================================================
--- pecl/krb5/tags/krb5-1.1.0/trunk/tests/003.phpt	                        (rev 0)
+++ pecl/krb5/tags/krb5-1.1.0/trunk/tests/003.phpt	2016-07-16 14:46:31 UTC (rev \
339676) @@ -0,0 +1,68 @@
+--TEST--
+Testing for GSSAPI wrap/unwrap/Mic code
+--SKIPIF--
+<?php
+if(!file_exists(dirname(__FILE__) . '/config.php')) { echo "skip config missing"; \
return; } +if(!include(dirname(__FILE__) . '/config.php')) return;
+?>
+--FILE--
+<?php
+include(dirname(__FILE__) . '/config.php');
+$client = new KRB5CCache();
+if($use_config) {
+	$client->setConfig(dirname(__FILE__) . '/krb5.ini');
+}
+
+$client->initPassword($client_principal, $client_password, array('tkt_life' => \
360)); +
+$server = new KRB5CCache();
+if($use_config) {
+        $server->setConfig(dirname(__FILE__) . '/krb5.ini');
+}
+
+$server->initKeytab($server_principal, $server_keytab);
+
+$cgssapi = new GSSAPIContext();
+$sgssapi = new GSSAPIContext();
+
+$cgssapi->acquireCredentials($client, $client_principal, GSS_C_INITIATE);
+$sgssapi->acquireCredentials($server, $server_principal, GSS_C_ACCEPT);
+
+$token = '';
+
+var_dump($cgssapi->initSecContext($server_principal, null, null, null, $token));
+var_dump($sgssapi->acceptSecContext($token));
+
+
+
+$message = base64_decode('RKkOxMZ64GwEdZf+vZ6bp4mVQ4E=');
+$mic = $sgssapi->getMic($message);
+var_dump($cgssapi->verifyMic($message, $mic));
+var_dump(@$cgssapi->verifyMic($message, $mic . '-'));
+var_dump(@$cgssapi->verifyMic($message . '-', $mic));
+
+$enc = '';
+var_dump($sgssapi->wrap($message, $enc,true));
+var_dump($enc !== $message);
+var_dump($cgssapi->unwrap($enc, $decoded));
+var_dump($decoded === $message);
+var_dump($cgssapi->wrap($message, $enc));
+var_dump($enc !== $message);
+var_dump($sgssapi->unwrap($enc, $decoded));
+var_dump($decoded === $message);
+
+?>
+--EXPECTF--
+bool(true)
+bool(true)
+bool(true)
+bool(false)
+bool(false)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)

Copied: pecl/krb5/tags/krb5-1.1.0/trunk/tests/004.phpt (from rev 339675, \
pecl/krb5/trunk/tests/004.phpt) \
                ===================================================================
--- pecl/krb5/tags/krb5-1.1.0/trunk/tests/004.phpt	                        (rev 0)
+++ pecl/krb5/tags/krb5-1.1.0/trunk/tests/004.phpt	2016-07-16 14:46:31 UTC (rev \
339676) @@ -0,0 +1,42 @@
+--TEST--
+Testing for working mutual authentication
+--SKIPIF--
+<?php
+if(!file_exists(dirname(__FILE__) . '/config.php')) { echo "skip config missing"; \
return; } +if(!include(dirname(__FILE__) . '/config.php')) return;
+?>
+--FILE--
+<?php
+include(dirname(__FILE__) . '/config.php');
+$client = new KRB5CCache();
+if($use_config) {
+	$client->setConfig(dirname(__FILE__) . '/krb5.ini');
+}
+
+$client->initPassword($client_principal, $client_password, array('tkt_life' => \
360)); +
+$server = new KRB5CCache();
+if($use_config) {
+        $server->setConfig(dirname(__FILE__) . '/krb5.ini');
+}
+
+$server->initKeytab($server_principal, $server_keytab);
+
+$cgssapi = new GSSAPIContext();
+$sgssapi = new GSSAPIContext();
+
+$cgssapi->acquireCredentials($client);
+$sgssapi->acquireCredentials($server);
+
+$token = '';
+$token2 = '';
+
+var_dump($cgssapi->initSecContext($server_principal, null, GSS_C_MUTUAL_FLAG, null, \
$token)); +var_dump($sgssapi->acceptSecContext($token, $token2));
+var_dump($cgssapi->initSecContext($server_principal, $token2, GSS_C_MUTUAL_FLAG, \
null, $token)); +
+?>
+--EXPECTF--
+bool(false)
+bool(true)
+bool(true)

Copied: pecl/krb5/tags/krb5-1.1.0/trunk/tests/005.phpt (from rev 339675, \
pecl/krb5/trunk/tests/005.phpt) \
                ===================================================================
--- pecl/krb5/tags/krb5-1.1.0/trunk/tests/005.phpt	                        (rev 0)
+++ pecl/krb5/tags/krb5-1.1.0/trunk/tests/005.phpt	2016-07-16 14:46:31 UTC (rev \
339676) @@ -0,0 +1,64 @@
+--TEST--
+Testing for working credential delegation
+--SKIPIF--
+<?php
+if(!file_exists(dirname(__FILE__) . '/config.php')) { echo "skip config missing"; \
return; } +if(!include(dirname(__FILE__) . '/config.php')) return;
+?>
+--FILE--
+<?php
+include(dirname(__FILE__) . '/config.php');
+$client = new KRB5CCache();
+if($use_config) {
+	$client->setConfig(dirname(__FILE__) . '/krb5.ini');
+}
+
+$client->initPassword($client_principal, $client_password, array('forwardable' => \
true , 'proxiable' => true)); +
+$server = new KRB5CCache();
+if($use_config) {
+        $server->setConfig(dirname(__FILE__) . '/krb5.ini');
+}
+
+$server->initKeytab($server_principal, $server_keytab);
+
+$cgssapi = new GSSAPIContext();
+$sgssapi = new GSSAPIContext();
+
+$cgssapi->acquireCredentials($client);
+$sgssapi->acquireCredentials($server);
+
+$token = '';
+$token2 = '';
+$prinicipal = '';
+$time_rec = 0;
+$ret_flags = '';
+$deleg = new KRB5CCache();
+
+var_dump($cgssapi->initSecContext($server_principal, null, GSS_C_DELEG_FLAG, null, \
$token)); +var_dump($sgssapi->acceptSecContext($token, $token2, $principal, \
$ret_flags, $time_rec, $deleg)); +var_dump(count($deleg->getEntries()));
+
+$dgssapi = new GSSAPIContext();
+$dgssapi->acquireCredentials($deleg, $principal, GSS_C_INITIATE);
+
+
+$s2gssapi = new GSSAPIContext();
+$s2gssapi->acquireCredentials($server);
+
+$token = '';
+$token2 = '';
+$principal2 = '';
+
+var_dump($dgssapi->initSecContext($server_principal, null, null, null, $token));
+var_dump($s2gssapi->acceptSecContext($token, $token2, $principal2, $ret_flags, \
$time_rec, $deleg)); +var_dump($principal2 === $principal);
+
+?>
+--EXPECTF--
+bool(true)
+bool(true)
+int(1)
+bool(true)
+bool(true)
+bool(true)

Copied: pecl/krb5/tags/krb5-1.1.0/trunk/tests/config.php.dist (from rev 339675, \
pecl/krb5/trunk/tests/config.php.dist) \
                ===================================================================
--- pecl/krb5/tags/krb5-1.1.0/trunk/tests/config.php.dist	                        \
                (rev 0)
+++ pecl/krb5/tags/krb5-1.1.0/trunk/tests/config.php.dist	2016-07-16 14:46:31 UTC \
(rev 339676) @@ -0,0 +1,26 @@
+<?php
+
+// you have to configure two prinicipals to get this working
+// the client principal with a password, the server principal with a keytab
+$client_principal = '';
+$client_password = '';
+$server_principal = '';
+$server_keytab = dirname(__FILE__) . '/server.keytab';
+
+if(!$client_principal || !$server_principal) {
+	echo "skip unconfigured";
+	return false;
+}
+
+if(!file_exists($server_keytab)) {
+	echo "skip keytab missing";
+	return false;
+}
+
+$use_config = false;
+if(file_exists(dirname(__FILE__) . '/krb5.ini')) {
+	$use_config = true;
+}
+
+return true;
+?>



-- 
PECL CVS Mailing List 
To unsubscribe, visit: http://www.php.net/unsub.php

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic