24697585 Userland krb5 should have a stricter set of compiler flags
authorWill Fiveash <will.fiveash@oracle.com>
Tue, 27 Sep 2016 15:08:33 -0500
changeset 6987 e80772ec96e1
parent 6984 a594fe3c9343
child 6988 5da30fb358bc
24697585 Userland krb5 should have a stricter set of compiler flags
components/krb5/Makefile
components/krb5/patches/028-rpc-gss.patch
components/krb5/patches/032-pam-krb5.patch
components/krb5/patches/074-stricter-compile-flags.patch
--- a/components/krb5/Makefile	Tue Sep 27 14:20:45 2016 -0700
+++ b/components/krb5/Makefile	Tue Sep 27 15:08:33 2016 -0500
@@ -62,6 +62,20 @@
 
 # We need to enable large file support and build PIC for our shared libraries
 CFLAGS += $(CPP_LARGEFILES) $(CC_PIC)
+CFLAGS += -errtags=yes -errwarn=%all
+CFLAGS += -errwarn=no%E_STATEMENT_NOT_REACHED
+CFLAGS += -errwarn=no%E_NO_IMPLICIT_DECL_ALLOWED
+CFLAGS += -errwarn=no%E_EMPTY_TRANSLATION_UNIT
+CFLAGS += -errwarn=no%E_EMPTY_INITIALIZER
+CFLAGS += -errwarn=no%E_EMPTY_DECLARATION
+CFLAGS += -errwarn=no%E_ENUM_VAL_OVERFLOWS_INT_MAX
+CFLAGS += -errwarn=no%E_DEPRECATED_ATT
+CFLAGS += -errwarn=no%E_INIT_SIGN_EXTEND
+# XXX really E_ASSIGNMENT_TYPE_MISMATCH should not be treated as a warning but
+# making this an error would require patching MIT code which I do not want to
+# do at this moment.  Making this an error should be revisited after rebasing
+# to MIT v1.15.
+CFLAGS += -errwarn=no%E_ASSIGNMENT_TYPE_MISMATCH
 
 # Include openldap headers instead of obsolete mozilla ldap headers.
 CPPFLAGS += -I$(USRINCDIR)/openldap
--- a/components/krb5/patches/028-rpc-gss.patch	Tue Sep 27 14:20:45 2016 -0700
+++ b/components/krb5/patches/028-rpc-gss.patch	Tue Sep 27 15:08:33 2016 -0500
@@ -261,7 +261,24 @@
  	  krb5_klog_syslog(LOG_ERR, "Authentication attempt failed: %s, "
  			   "RPC authentication flavor %d",
  			   client_addr(rqstp->rq_xprt),
-@@ -246,6 +245,8 @@ void kadm_1(rqstp, transp)
+@@ -229,7 +228,7 @@ void kadm_1(rqstp, transp)
+ 	  return;
+      }
+      memset(&argument, 0, sizeof(argument));
+-     if (!svc_getargs(transp, xdr_argument, &argument)) {
++     if (!svc_getargs(transp, xdr_argument, (char *)&argument)) {
+ 	  svcerr_decode(transp);
+ 	  return;
+      }
+@@ -239,13 +238,15 @@ void kadm_1(rqstp, transp)
+ 		 "continuing.");
+ 	  svcerr_systemerr(transp);
+      }
+-     if (!svc_freeargs(transp, xdr_argument, &argument)) {
++     if (!svc_freeargs(transp, xdr_argument, (char *)&argument)) {
+ 	  krb5_klog_syslog(LOG_ERR, "WARNING! Unable to free arguments, "
+ 		 "continuing.");
+      }
       return;
  }
  
@@ -337,7 +354,11 @@
 +        fail_to_start(ENOMEM, _("copying GSSAPI auth names"));
 +    free_srv_names(tmp_srv_names);
 +    tmp_srv_names = NULL;
-+
+ 
+-    names[0].name = build_princ_name(KADM5_ADMIN_SERVICE, params.realm);
+-    names[1].name = build_princ_name(KADM5_CHANGEPW_SERVICE, params.realm);
+-    if (names[0].name == NULL || names[1].name == NULL)
+-        fail_to_start(0, _("Cannot build GSSAPI auth names"));
 +    ret = kadm5_get_cpw_host_srv_names(context, params.realm, &tmp_srv_names);
 +    if (ret)
 +        fail_to_start(ret, _("building GSSAPI auth names"));
@@ -346,11 +367,7 @@
 +        fail_to_start(ENOMEM, _("copying GSSAPI auth names"));
 +    free_srv_names(tmp_srv_names);
 +    tmp_srv_names = NULL;
- 
--    names[0].name = build_princ_name(KADM5_ADMIN_SERVICE, params.realm);
--    names[1].name = build_princ_name(KADM5_CHANGEPW_SERVICE, params.realm);
--    if (names[0].name == NULL || names[1].name == NULL)
--        fail_to_start(0, _("Cannot build GSSAPI auth names"));
++
 +    if (params.iprop_enabled == TRUE) {
 +        ret = kadm5_get_kiprop_host_srv_names(context, params.realm,
 +                                              &tmp_srv_names);
@@ -489,14 +506,14 @@
 -    if (! gss_to_krb5_name(handle, rqst2name(rqstp),
 -                           &handle->current_caller)) {
 +    if (!(name = rqst2name(rqstp))) {
+         free(handle);
+         return KADM5_FAILURE;
+     }
++    if (! gss_to_krb5_name(handle, name, &handle->current_caller)) {
 +        free(handle);
++        gss_release_name(&min_stat, &name);
 +        return KADM5_FAILURE;
 +    }
-+    if (! gss_to_krb5_name(handle, name, &handle->current_caller)) {
-         free(handle);
-+        gss_release_name(&min_stat, &name);
-         return KADM5_FAILURE;
-     }
  
      *out_handle = handle;
 +    gss_release_name(&min_stat, &name);
@@ -551,7 +568,12 @@
 +    gss_name_t name = NULL;
 +    rpc_gss_rawcred_t *raw_cred;
 +    gss_buffer_desc name_buff;
-+
+ 
+-    maj_stat = gss_inquire_context(&min_stat, context, NULL, &name,
+-                                   NULL, NULL, NULL, NULL, NULL);
+-    if (maj_stat != GSS_S_COMPLETE)
+-        return NULL;
+-    return name;
 +    rpc_gss_getcred(rqstp, &raw_cred, NULL, NULL);
 +    name_buff.value = raw_cred->svc_principal;
 +    name_buff.length = strlen(raw_cred->svc_principal);
@@ -567,12 +589,7 @@
 +      return (NULL);
 +    }
 +    gss_release_buffer(&min_stat, &name_buff);
- 
--    maj_stat = gss_inquire_context(&min_stat, context, NULL, &name,
--                                   NULL, NULL, NULL, NULL, NULL);
--    if (maj_stat != GSS_S_COMPLETE)
--        return NULL;
--    return name;
++
 +     return name;
  }
  
@@ -1382,16 +1399,15 @@
  gss_name_t
  rqst2name(struct svc_req *rqstp)
  {
--
++    OM_uint32 maj_stat, min_stat;
++    gss_name_t name;
++    rpc_gss_rawcred_t * raw_cred;
++    gss_buffer_desc name_buff;
+ 
 -    if (rqstp->rq_cred.oa_flavor == RPCSEC_GSS)
 -        return rqstp->rq_clntname;
 -    else
 -        return rqstp->rq_clntcred;
-+    OM_uint32 maj_stat, min_stat;
-+    gss_name_t name;
-+    rpc_gss_rawcred_t * raw_cred;
-+    gss_buffer_desc name_buff;
-+
 +    rpc_gss_getcred(rqstp, &raw_cred, NULL, NULL);
 +    name_buff.value = raw_cred->client_principal->name;
 +    name_buff.length = raw_cred->client_principal->len;
@@ -1636,16 +1652,19 @@
 +    void *handlep;
 +    struct netconfig *nconf, *nconf4 = NULL, *nconf6 = NULL;
 +    char *protofmly = NULL;
-+
+ 
+-    memset(&sin4, 0, sizeof(sin4));
+-    sin4.sin_family = AF_INET;
+-    sin4.sin_addr.s_addr = INADDR_ANY;
 +    /* pick the right network: tcp and tcp6 */
 +    if ((handlep = setnetconfig()) == NULL) {
 +        com_err(data->prog, errno, _("cannot get any transport information"));
 +        goto cleanup;
 +    }
  
--    memset(&sin4, 0, sizeof(sin4));
--    sin4.sin_family = AF_INET;
--    sin4.sin_addr.s_addr = INADDR_ANY;
+-    memset(&sin6, 0, sizeof(sin6));
+-    sin6.sin6_family = AF_INET6;
+-    sin6.sin6_addr = in6addr_any;
 +    while (nconf = getnetconfig(handlep)) {
 +        if ((nconf->nc_semantics == NC_TPI_COTS_ORD) &&
 +            (strcmp(nconf->nc_proto, NC_TCP) == 0)){
@@ -1655,10 +1674,7 @@
 +                    nconf6 = nconf;
 +        }
 +    }
- 
--    memset(&sin6, 0, sizeof(sin6));
--    sin6.sin6_family = AF_INET6;
--    sin6.sin6_addr = in6addr_any;
++
 +    if (nconf4 == NULL && nconf6 == NULL) {
 +        com_err(data->prog, 0, _("no transport with proto=%s"), NC_TCP);
 +        goto cleanup;
@@ -1667,7 +1683,10 @@
      FOREACH_ELT (rpc_svc_data, i, svc) {
 -        int s4;
 -        int s6;
--
++        fd = create_server_endpoint(data, nconf4, svc.port);
++        if (fd < 0)
++            goto cleanup;
+ 
 -        sa_setport((struct sockaddr *)&sin4, svc.port);
 -        s4 = create_server_socket(data, (struct sockaddr *)&sin4, SOCK_STREAM);
 -        if (s4 < 0)
@@ -1678,10 +1697,6 @@
 -        else
 -            krb5_klog_syslog(LOG_INFO, _("listening on fd %d: rpc %s"),
 -                             s4, paddr((struct sockaddr *)&sin4));
-+        fd = create_server_endpoint(data, nconf4, svc.port);
-+        if (fd < 0)
-+            goto cleanup;
-+
 +        if (add_rpc_listener_fd(data, nconf4, &svc, fd) == NULL)
 +            close(fd);
 +        else {
@@ -2144,7 +2159,7 @@
 +	/* Set a one-hour timeout. */
 +	timeout.tv_sec = 3600;
 +	timeout.tv_usec = 0;
-+	(void)clnt_control(handle->clnt, CLSET_TIMEOUT, &timeout);
++	(void)clnt_control(handle->clnt, CLSET_TIMEOUT, (char *)&timeout);
 +
 +	handle->lhandle->clnt = handle->clnt;
 +
@@ -2158,7 +2173,7 @@
 +	 */
 +	/* use the kadm5 cache */
 +	gssstat = gss_krb5_ccache_name(&minor_stat, handle->cache_name,
-+                                       &ccname_orig);
++                                       (const char **)&ccname_orig);
 +	if (gssstat != GSS_S_COMPLETE) {
 +		code = KADM5_GSS_ERROR;
 +		goto error;
@@ -2308,11 +2323,25 @@
 -     * Get credentials.  Also does some fallbacks in case kadmin/fqdn
 -     * principal doesn't exist.
 -     */
--    code = get_init_creds(handle, client, init_type, pass, ccache_in,
++    /* NULL svcname means use host-based. */
++    if (svcname_in == NULL) {
++        code = kadm5_get_admin_service_name(handle->context,
++                                            handle->params.realm,
++                                            svcname, sizeof(svcname));
++        if (code)
++            goto error;
++    } else {
++        strncpy(svcname, svcname_in, sizeof(svcname));
++        svcname[sizeof(svcname)-1] = '\0';
++    }
++
++    /* Get credentials. */
+     code = get_init_creds(handle, client, init_type, pass, ccache_in,
 -                          service_name, handle->params.realm, &server);
--    if (code)
--        goto error;
--
++                          svcname, handle->params.realm, &server);
+     if (code)
+         goto error;
+ 
 -    /* If the service_name and client_name are iprop-centric, use the iprop
 -     * port and RPC identifiers. */
 -    iprop_enable = (service_name != NULL &&
@@ -2322,14 +2351,7 @@
 -        port = handle->params.iprop_port;
 -        rpc_prog = KRB5_IPROP_PROG;
 -        rpc_vers = KRB5_IPROP_VERS;
-+    /* NULL svcname means use host-based. */
-+    if (svcname_in == NULL) {
-+        code = kadm5_get_admin_service_name(handle->context,
-+                                            handle->params.realm,
-+                                            svcname, sizeof(svcname));
-+        if (code)
-+            goto error;
-     } else {
+-    } else {
 -        port = handle->params.kadmind_port;
 -        rpc_prog = KADM;
 -        rpc_vers = KADMVERS;
@@ -2346,10 +2368,8 @@
 -        clnt_pcreateerror("clnttcp_create");
 -#endif
 -        goto error;
-+        strncpy(svcname, svcname_in, sizeof(svcname));
-+        svcname[sizeof(svcname)-1] = '\0';
-     }
- 
+-    }
+-
 -    /* Set a one-hour timeout. */
 -    timeout.tv_sec = 3600;
 -    timeout.tv_usec = 0;
@@ -2369,12 +2389,9 @@
 -     */
 -    code = setup_gss(handle, params_in,
 -                     (init_type == INIT_CREDS) ? client : NULL, server);
-+    /* Get credentials. */
-+    code = get_init_creds(handle, client, init_type, pass, ccache_in,
-+                          svcname, handle->params.realm, &server);
-     if (code)
-         goto error;
- 
+-    if (code)
+-        goto error;
+-
 -    /*
 -     * Bypass the remainder of the code and return straightaway
 -     * if the gss service requested is kiprop
@@ -2908,7 +2925,7 @@
  #include <memory.h>
 --- a/src/slave/kpropd.c
 +++ b/src/slave/kpropd.c
-@@ -588,7 +588,7 @@ full_resync(CLIENT *clnt)
+@@ -588,12 +588,12 @@ full_resync(CLIENT *clnt)
  
      memset(&clnt_res, 0, sizeof(clnt_res));
  
@@ -2917,6 +2934,12 @@
                         (caddr_t)&vers, (xdrproc_t)xdr_kdb_fullresync_result_t,
                         (caddr_t)&clnt_res, full_resync_timeout);
      if (status == RPC_PROCUNAVAIL) {
+         status = clnt_call(clnt, IPROP_FULL_RESYNC, (xdrproc_t)xdr_void,
+-                           (caddr_t *)&vers,
++                           (caddr_t)&vers,
+                            (xdrproc_t)xdr_kdb_fullresync_result_t,
+                            (caddr_t)&clnt_res, full_resync_timeout);
+     }
 --- a/src/tests/misc/Makefile.in
 +++ b/src/tests/misc/Makefile.in
 @@ -12,18 +12,16 @@ SRCS=\
@@ -3041,7 +3064,7 @@
 -         fail('Expected old serial %d from kpropd sync' % expected_old)
 -    if new_sno != expected_new:
 -         fail('Expected new serial %d from kpropd sync' % expected_new)
--
+ 
 -    # Wait until kpropd is sleeping before continuing, to avoid races.
 -    # (This is imperfect since there's there is a short window between
 -    # the fprintf and the sleep; kpropd will need design changes to
@@ -3052,6 +3075,12 @@
 -        if 'Waiting for' in line:
 -            break
 -    output('*** Sync complete\n')
++# Verify the iprop log last serial number against an expected value,
++# on either the master or slave.
++def check_serial(realm, expected, env=None):
++    out = realm.run([kproplog, '-h'], env=env)
++    if 'Last serial # : ' not in out:
++        fail('Unexpected serial number')
  
 -# Verify the output of kproplog against the expected number of
 -# entries, first and last serial number, and a list of principal names
@@ -3087,12 +3116,6 @@
 -            eprinc = entries[ser - first]
 -            if eprinc != None:
 -                fail('Expected princ %s in update entry %d' % (eprinc, ser))
-+# Verify the iprop log last serial number against an expected value,
-+# on either the master or slave.
-+def check_serial(realm, expected, env=None):
-+    out = realm.run([kproplog, '-h'], env=env)
-+    if 'Last serial # : ' not in out:
-+        fail('Unexpected serial number')
  
 -# slave1 will receive updates from master, and slave2 will receive
 -# updates from slave1.  Because of the awkward way iprop and kprop
@@ -3111,16 +3134,22 @@
 -                                     'iprop_logfile': '$testdir/ulog.slave2',
 -                                     'iprop_port': '$port8'}},
 -               'dbmodules': {'db': {'database_name': '$testdir/db.slave2'}}}
- 
--realm = K5Realm(kdc_conf=conf, create_user=False, start_kadmind=True)
--slave1 = realm.special_env('slave1', True, kdc_conf=conf_slave1)
--slave1m = realm.special_env('slave1m', True, kdc_conf=conf_slave1m)
--slave2 = realm.special_env('slave2', True, kdc_conf=conf_slave2)
 +conf = {
 +    'realms': {'$realm': {
 +            'iprop_enable': 'true',
 +            'iprop_logfile' : '$testdir/db.ulog'}}}
++
++conf_slave = {
++    'realms': {'$realm': {
++            'iprop_slave_poll': '600',
++            'iprop_logfile' : '$testdir/db.slave.ulog'}},
++    'dbmodules': {'db': {'database_name': '$testdir/db.slave'}}}
  
+ realm = K5Realm(kdc_conf=conf, create_user=False, start_kadmind=True)
+-slave1 = realm.special_env('slave1', True, kdc_conf=conf_slave1)
+-slave1m = realm.special_env('slave1m', True, kdc_conf=conf_slave1m)
+-slave2 = realm.special_env('slave2', True, kdc_conf=conf_slave2)
+-
 -# Define some principal names.  pr3 is long enough to cause internal
 -# reallocs, but not long enough to grow the basic ulog entry size.
 -pr1 = 'wakawaka@' + realm.realm
@@ -3129,18 +3158,12 @@
 -cs = c + '/'
 -pr3 = (cs + cs + cs + cs + cs + cs + cs + cs + cs + cs + cs + cs + c +
 -       '@' + realm.realm)
-+conf_slave = {
-+    'realms': {'$realm': {
-+            'iprop_slave_poll': '600',
-+            'iprop_logfile' : '$testdir/db.slave.ulog'}},
-+    'dbmodules': {'db': {'database_name': '$testdir/db.slave'}}}
- 
+-
 -# Create the kpropd ACL file.
 -acl_file = os.path.join(realm.testdir, 'kpropd-acl')
 -acl = open(acl_file, 'w')
 -acl.write(realm.host_princ + '\n')
 -acl.close()
-+realm = K5Realm(kdc_conf=conf, create_user=False, start_kadmind=True)
 +slave = realm.special_env('slave', True, kdc_conf=conf_slave)
  
  ulog = os.path.join(realm.testdir, 'db.ulog')
@@ -3173,8 +3196,6 @@
 +realm.addprinc('w')
 +realm.run([kadminl, 'modprinc', '-allow_tix', 'w'])
 +realm.run([kadminl, 'modprinc', '+allow_tix', 'w'])
-+
-+check_serial(realm, '7')
  
 -# Make some changes to the master DB.
 -realm.addprinc(pr1)
@@ -3183,11 +3204,7 @@
 -realm.run([kadminl, 'modprinc', '-allow_tix', pr2])
 -realm.run([kadminl, 'modprinc', '+allow_tix', pr2])
 -check_ulog(6, 1, 6, [None, pr1, pr3, pr2, pr2, pr2])
-+# Set up the kpropd acl file.
-+acl_file = os.path.join(realm.testdir, 'kpropd-acl')
-+acl = open(acl_file, 'w')
-+acl.write(realm.host_princ + '\n')
-+acl.close()
++check_serial(realm, '7')
  
 -# Start kpropd for slave1 and get a full dump from master.
 -kpropd1 = realm.start_kpropd(slave1, ['-d'])
@@ -3196,6 +3213,12 @@
 -if pr1 not in out or pr2 not in out or pr3 not in out:
 -    fail('slave1 does not have all principals from master')
 -check_ulog(1, 6, 6, [None], slave1)
++# Set up the kpropd acl file.
++acl_file = os.path.join(realm.testdir, 'kpropd-acl')
++acl = open(acl_file, 'w')
++acl.write(realm.host_princ + '\n')
++acl.close()
++
 +# Start kpropd and get a full dump from master.
 +kpropd = realm.start_kpropd(slave, ['-d'])
 +wait_for_prop(kpropd, True)
@@ -3218,7 +3241,8 @@
 +out = realm.run([kadminl, 'getprinc', 'w'], env=slave)
  if 'Attributes: DISALLOW_ALL_TIX' not in out:
 -    fail('slave1 does not have modification from master')
--
++    fail('Slave does not have modification from master')
+ 
 -# Start kadmind -proponly for slave1.  (Use the slave1m environment
 -# which defines iprop_port to $port8.)
 -slave1_out_dump_path = os.path.join(realm.testdir, 'dump.slave1.out')
@@ -3228,8 +3252,7 @@
 -realm.start_server([kadmind, '-nofork', '-proponly', '-W', '-p', kdb5_util,
 -                    '-K', kprop, '-F', slave1_out_dump_path], 'starting...',
 -                   slave1m)
-+    fail('Slave does not have modification from master')
- 
+-
 -# Start kpropd for slave2.  The -A option isn't needed since we're
 -# talking to the same host as master (we specify it anyway to exercise
 -# the code), but slave2 defines iprop_port to $port8 so it will talk
@@ -3297,18 +3320,18 @@
 -wait_for_prop(kpropd1, False, 8, 9)
 -check_ulog(4, 6, 9, [None, pr2, pr1, pr2], slave1)
 -out = realm.run([kadminl, 'getprinc', pr2], env=slave1)
+-if 'Attributes:\n' not in out:
+-    fail('slave1 does not have modification from master')
+-kpropd2.send_signal(signal.SIGUSR1)
+-wait_for_prop(kpropd2, False, 8, 9)
+-check_ulog(3, 7, 9, [None, pr1, pr2], slave2)
+-out = realm.run([kadminl, 'getprinc', pr2], env=slave2)
 +check_serial(realm, '10')
 +kpropd.send_signal(signal.SIGUSR1)
 +wait_for_prop(kpropd, False)
 +check_serial(realm, '10', slave)
 +out = realm.run([kadminl, 'getprinc', 'w'], env=slave)
  if 'Attributes:\n' not in out:
--    fail('slave1 does not have modification from master')
--kpropd2.send_signal(signal.SIGUSR1)
--wait_for_prop(kpropd2, False, 8, 9)
--check_ulog(3, 7, 9, [None, pr1, pr2], slave2)
--out = realm.run([kadminl, 'getprinc', pr2], env=slave2)
--if 'Attributes:\n' not in out:
 -    fail('slave2 does not have modification from slave1')
 +    fail('Slave has different state from master')
  
@@ -3319,18 +3342,18 @@
 -wait_for_prop(kpropd1, True, 9, 1)
 -check_ulog(1, 1, 1, [None], slave1)
 -out = realm.run([kadminl, 'getpol', 'testpol'], env=slave1)
--if 'Minimum number of password character classes: 2' not in out:
--    fail('slave1 does not have policy from master')
--kpropd2.send_signal(signal.SIGUSR1)
--wait_for_prop(kpropd2, True, 9, 1)
--check_ulog(1, 1, 1, [None], slave2)
--out = realm.run([kadminl, 'getpol', 'testpol'], env=slave2)
 +check_serial(realm, 'None')
 +kpropd.send_signal(signal.SIGUSR1)
 +wait_for_prop(kpropd, True)
 +check_serial(realm, 'None', slave)
 +out = realm.run([kadminl, 'getpol', 'testpol'], env=slave)
  if 'Minimum number of password character classes: 2' not in out:
+-    fail('slave1 does not have policy from master')
+-kpropd2.send_signal(signal.SIGUSR1)
+-wait_for_prop(kpropd2, True, 9, 1)
+-check_ulog(1, 1, 1, [None], slave2)
+-out = realm.run([kadminl, 'getpol', 'testpol'], env=slave2)
+-if 'Minimum number of password character classes: 2' not in out:
 -    fail('slave2 does not have policy from slave1')
 +    fail('Slave does not have policy from master')
  
@@ -3363,12 +3386,6 @@
 -wait_for_prop(kpropd1, True, 1, 1)
 -check_ulog(1, 1, 1, [None], slave1)
 -out = realm.run([kadminl, 'getpol', 'testpol'], env=slave1, expected_code=1)
--if 'Policy does not exist' not in out:
--    fail('slave1 did not get policy deletion from master')
--kpropd2.send_signal(signal.SIGUSR1)
--wait_for_prop(kpropd2, True, 1, 1)
--check_ulog(1, 1, 1, [None], slave2)
--out = realm.run([kadminl, 'getpol', 'testpol'], env=slave2, expected_code=1)
 +realm.run([kadminl, 'delpol', '-force', 'testpol'])
 +check_serial(realm, 'None')
 +kpropd.send_signal(signal.SIGUSR1)
@@ -3376,6 +3393,12 @@
 +check_serial(realm, 'None', slave)
 +out = realm.run([kadminl, 'getpol', 'testpol'], env=slave, expected_code=1)
  if 'Policy does not exist' not in out:
+-    fail('slave1 did not get policy deletion from master')
+-kpropd2.send_signal(signal.SIGUSR1)
+-wait_for_prop(kpropd2, True, 1, 1)
+-check_ulog(1, 1, 1, [None], slave2)
+-out = realm.run([kadminl, 'getpol', 'testpol'], env=slave2, expected_code=1)
+-if 'Policy does not exist' not in out:
 -    fail('slave2 did not get policy deletion from slave1')
 -
 -# Modify a principal on the master and test that it propagates incrementally.
@@ -3393,8 +3416,7 @@
 -out = realm.run([kadminl, 'getprinc', pr1], env=slave2)
 -if 'Maximum ticket life: 0 days 00:10:00' not in out:
 -    fail('slave2 does not have modification from slave1')
-+    fail('Slave did not get policy deletion from master')
- 
+-
 -# Delete a principal and test that it propagates incrementally.
 -realm.run([kadminl, 'delprinc', pr3])
 -check_ulog(3, 1, 3, [None, pr1, pr3])
@@ -3410,7 +3432,8 @@
 -out = realm.run([kadminl, 'getprinc', pr3], env=slave2, expected_code=1)
 -if 'Principal does not exist' not in out:
 -    fail('slave2 does not have principal deletion from slave1')
--
++    fail('Slave did not get policy deletion from master')
+ 
 -# Reset the ulog on the master to force a full resync.
 +# Reset the ulog on the master side to force a full resync to all slaves.
 +# XXX Note that we only have one slave in this test, so we can't really
--- a/components/krb5/patches/032-pam-krb5.patch	Tue Sep 27 14:20:45 2016 -0700
+++ b/components/krb5/patches/032-pam-krb5.patch	Tue Sep 27 15:08:33 2016 -0500
@@ -43,6 +43,15 @@
  
  	iprop_svc = strdup(KIPROP_SVC_NAME);
  	if (iprop_svc == NULL)
+@@ -442,7 +440,7 @@ _kadm5_initialize_rpcsec_gss_handle(kadm5_server_handle_t handle,
+ 
+ 	if (ccname_orig) {
+ 		gssstat = gss_krb5_ccache_name(&minor_stat, ccname_orig, NULL);
+-		free(ccname_orig);
++		free((void *)ccname_orig);
+ 		if (gssstat != GSS_S_COMPLETE) {
+ 			code = KADM5_GSS_ERROR;
+ 			goto error;
 @@ -516,7 +514,7 @@ cleanup:
  
  static kadm5_ret_t
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/krb5/patches/074-stricter-compile-flags.patch	Tue Sep 27 15:08:33 2016 -0500
@@ -0,0 +1,51 @@
+#
+# This patch provides support for compiling Userland krb5 with compiler flags
+# that will treat more code issues as errors rather than just warning.  The
+# code change to src/include/k5-utf8.h comes from upstream (MIT) and this code
+# change should be in MIT's next release 1.15 so this patch should be deleted
+# when Userland krb5 rebases to that release.
+# Patch source: upstream
+#
+--- a/src/include/k5-utf8.h
++++ b/src/include/k5-utf8.h
+@@ -68,37 +68,10 @@
+ #ifndef K5_UTF8_H
+ #define K5_UTF8_H
+ 
+-#include "autoconf.h"
++#include "k5-platform.h"
+ 
+-#ifdef HAVE_SYS_TYPES_H
+-#include <sys/types.h>
+-#endif
+-
+-#ifdef HAVE_UNISTD_H
+-#include <unistd.h>
+-#endif
+-
+-#ifdef HAVE_STDLIB_H
+-#include <stdlib.h>
+-#endif
+-
+-#if INT_MAX == 0x7fff
+-typedef unsigned int    krb5_ucs2;
+-#elif SHRT_MAX == 0x7fff
+-typedef unsigned short  krb5_ucs2;
+-#else
+-#error undefined 16 bit type
+-#endif
+-
+-#if INT_MAX == 0x7fffffffL
+-typedef int     krb5_ucs4;
+-#elif LONG_MAX == 0x7fffffffL
+-typedef long    krb5_ucs4;
+-#elif SHRT_MAX == 0x7fffffffL
+-typedef short   krb5_ucs4;
+-#else
+-#error: undefined 32 bit type
+-#endif
++typedef uint16_t krb5_ucs2;
++typedef uint32_t krb5_ucs4;
+ 
+ #define KRB5_MAX_UTF8_LEN   (sizeof(krb5_ucs2) * 3/2)
+