svn rev #25215: trunk/ doc/rst_source/krb_admins/admin_commands/ src/include/ ...

ghudson@MIT.EDU ghudson at MIT.EDU
Wed Sep 21 12:29:00 EDT 2011


http://src.mit.edu/fisheye/changelog/krb5/?cs=25215
Commit By: ghudson
Log Message:
Add kadmin functionality for string attributes.


Changed Files:
U   trunk/doc/rst_source/krb_admins/admin_commands/kadmin_local.rst
U   trunk/src/include/kdb.h
U   trunk/src/kadmin/cli/kadmin.M
U   trunk/src/kadmin/cli/kadmin.c
U   trunk/src/kadmin/cli/kadmin.h
U   trunk/src/kadmin/cli/kadmin_ct.ct
U   trunk/src/kadmin/server/kadm_rpc_svc.c
U   trunk/src/kadmin/server/ovsec_kadmd.c
U   trunk/src/kadmin/server/server_stubs.c
U   trunk/src/lib/kadm5/admin.h
U   trunk/src/lib/kadm5/admin_xdr.h
U   trunk/src/lib/kadm5/clnt/client_principal.c
U   trunk/src/lib/kadm5/clnt/client_rpc.c
U   trunk/src/lib/kadm5/clnt/libkadm5clnt_mit.exports
U   trunk/src/lib/kadm5/kadm_rpc.h
U   trunk/src/lib/kadm5/kadm_rpc_xdr.c
U   trunk/src/lib/kadm5/misc_free.c
U   trunk/src/lib/kadm5/srv/libkadm5srv_mit.exports
U   trunk/src/lib/kadm5/srv/svr_principal.c
U   trunk/src/tests/Makefile.in
A   trunk/src/tests/t_stringattr.py
Modified: trunk/doc/rst_source/krb_admins/admin_commands/kadmin_local.rst
===================================================================
--- trunk/doc/rst_source/krb_admins/admin_commands/kadmin_local.rst	2011-09-21 16:28:54 UTC (rev 25214)
+++ trunk/doc/rst_source/krb_admins/admin_commands/kadmin_local.rst	2011-09-21 16:29:00 UTC (rev 25215)
@@ -562,6 +562,43 @@
 
 .. _list_principals_end:
 
+.. _get_strings:
+
+get_strings
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+       **get_strings** *principal*
+              Displays string attributes on *principal*.
+	      String attributes are used to supply per-principal configuration to some KDC plugin modules.
+
+              Alias::
+
+                     getstr
+
+.. _set_string:
+
+set_string
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+       **set_string** *principal* *key* *value*
+              Sets a string attribute on *principal*.
+
+              Alias::
+
+                     setstr
+
+.. _del_string:
+
+del_string
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+       **del_string** *principal* *key*
+              Deletes a string attribute from *principal*.
+
+              Alias::
+
+                     delstr
+
 .. _add_policy:
 
 add_policy

Modified: trunk/src/include/kdb.h
===================================================================
--- trunk/src/include/kdb.h	2011-09-21 16:28:54 UTC (rev 25214)
+++ trunk/src/include/kdb.h	2011-09-21 16:29:00 UTC (rev 25215)
@@ -243,7 +243,7 @@
 #define KRB5_TL_MKEY_AUX                0x000a
 
 /* String attributes may not always be represented in tl-data.  kadmin clients
- * must use the modify_strings and get_strings RPCs. */
+ * must use the get_strings and set_string RPCs. */
 #define KRB5_TL_STRING_ATTRS            0x000b
 
 #define KRB5_TL_PAC_LOGON_INFO          0x0100 /* NDR encoded validation info */

Modified: trunk/src/kadmin/cli/kadmin.M
===================================================================
--- trunk/src/kadmin/cli/kadmin.M	2011-09-21 16:28:54 UTC (rev 25214)
+++ trunk/src/kadmin/cli/kadmin.M	2011-09-21 16:29:00 UTC (rev 25215)
@@ -672,6 +672,28 @@
 .RE
 .fi
 .TP
+\fBget_strings\fP \fIprincipal\fP
+displays string attributes on
+.IR principal .
+String attributes are used to supply per-principal configuration to
+some KDC plugin modules.  Alias
+.BR getstrs .
+.fi
+.TP
+\fBset_string\fP \fIprincipal\fP \fIkey\fP \fIvalue\fP
+sets a string attribute on
+.IR principal .
+Alias
+.BR setstr .
+.fi
+.TP
+\fBdel_string\fP \fIprincipal\fP \fIkey\fP
+deletes a string attribute from
+.IR principal .
+Alias
+.BR delstr .
+.fi
+.TP
 \fBadd_policy\fP [\fIoptions\fP] \fIpolicy\fP
 adds the named policy to the policy database.  Requires the
 .I add

Modified: trunk/src/kadmin/cli/kadmin.c
===================================================================
--- trunk/src/kadmin/cli/kadmin.c	2011-09-21 16:28:54 UTC (rev 25214)
+++ trunk/src/kadmin/cli/kadmin.c	2011-09-21 16:29:00 UTC (rev 25215)
@@ -1898,3 +1898,130 @@
     free(canon);
     return;
 }
+
+void
+kadmin_getstrings(int argc, char *argv[])
+{
+    kadm5_ret_t retval;
+    char *pname, *canon = NULL;
+    krb5_principal princ = NULL;
+    krb5_string_attr *strings = NULL;
+    int count, i;
+
+    if (argc != 2) {
+        fprintf(stderr, _("usage: get_strings principal\n"));
+        return;
+    }
+    pname = argv[1];
+
+    retval = kadmin_parse_name(pname, &princ);
+    if (retval) {
+        com_err("get_strings", retval, _("while parsing principal"));
+        return;
+    }
+
+    retval = krb5_unparse_name(context, princ, &canon);
+    if (retval) {
+        com_err("get_strings", retval, _("while canonicalizing principal"));
+        goto cleanup;
+    }
+
+    retval = kadm5_get_strings(handle, princ, &strings, &count);
+    if (retval) {
+        com_err("get_strings", retval,
+                _("while getting attributes for principal \"%s\""), canon);
+        goto cleanup;
+    }
+
+    if (count == 0)
+        printf(_("(No string attributes.)\n"));
+    for (i = 0; i < count; i++)
+        printf("%s: %s\n", strings[i].key, strings[i].value);
+    kadm5_free_strings(handle, strings, count);
+
+cleanup:
+    krb5_free_principal(context, princ);
+    free(canon);
+    return;
+}
+
+void
+kadmin_setstring(int argc, char *argv[])
+{
+    kadm5_ret_t retval;
+    char *pname, *canon = NULL, *key, *value;
+    krb5_principal princ = NULL;
+
+    if (argc != 4) {
+        fprintf(stderr, _("usage: set_string principal key value\n"));
+        return;
+    }
+    pname = argv[1];
+    key = argv[2];
+    value = argv[3];
+
+    retval = kadmin_parse_name(pname, &princ);
+    if (retval) {
+        com_err("set_string", retval, _("while parsing principal"));
+        return;
+    }
+
+    retval = krb5_unparse_name(context, princ, &canon);
+    if (retval) {
+        com_err("set_string", retval, _("while canonicalizing principal"));
+        goto cleanup;
+    }
+
+    retval = kadm5_set_string(handle, princ, key, value);
+    if (retval) {
+        com_err("set_string", retval,
+                _("while setting attribute on principal \"%s\""), canon);
+        goto cleanup;
+    }
+
+    printf(_("Attribute set for principal \"%s\".\n"), canon);
+cleanup:
+    krb5_free_principal(context, princ);
+    free(canon);
+    return;
+}
+
+void
+kadmin_delstring(int argc, char *argv[])
+{
+    kadm5_ret_t retval;
+    char *pname, *canon = NULL, *key;
+    krb5_principal princ = NULL;
+
+    if (argc != 3) {
+        fprintf(stderr, _("usage: del_string principal key\n"));
+        return;
+    }
+    pname = argv[1];
+    key = argv[2];
+
+    retval = kadmin_parse_name(pname, &princ);
+    if (retval) {
+        com_err("delstring", retval, _("while parsing principal"));
+        return;
+    }
+
+    retval = krb5_unparse_name(context, princ, &canon);
+    if (retval) {
+        com_err("del_string", retval, _("while canonicalizing principal"));
+        goto cleanup;
+    }
+
+    retval = kadm5_set_string(handle, princ, key, NULL);
+    if (retval) {
+        com_err("del_string", retval,
+                _("while deleting attribute from principal \"%s\""), canon);
+        goto cleanup;
+    }
+
+    printf(_("Attribute removed from principal \"%s\".\n"), canon);
+cleanup:
+    krb5_free_principal(context, princ);
+    free(canon);
+    return;
+}

Modified: trunk/src/kadmin/cli/kadmin.h
===================================================================
--- trunk/src/kadmin/cli/kadmin.h	2011-09-21 16:28:54 UTC (rev 25214)
+++ trunk/src/kadmin/cli/kadmin.h	2011-09-21 16:29:00 UTC (rev 25215)
@@ -53,6 +53,9 @@
 extern void kadmin_keytab_add(int argc, char *argv[]);
 extern void kadmin_keytab_remove(int argc, char *argv[]);
 extern void kadmin_purgekeys(int argc, char *argv[]);
+extern void kadmin_getstrings(int argc, char *argv[]);
+extern void kadmin_setstring(int argc, char *argv[]);
+extern void kadmin_delstring(int argc, char *argv[]);
 
 #include "autoconf.h"
 

Modified: trunk/src/kadmin/cli/kadmin_ct.ct
===================================================================
--- trunk/src/kadmin/cli/kadmin_ct.ct	2011-09-21 16:28:54 UTC (rev 25214)
+++ trunk/src/kadmin/cli/kadmin_ct.ct	2011-09-21 16:29:00 UTC (rev 25215)
@@ -80,6 +80,15 @@
 request kadmin_purgekeys, "Purge previously retained old keys from a principal",
 	purgekeys;
 
+request kadmin_getstrings, "Show string attributes on a principal",
+	get_strings, getstrs;
+
+request kadmin_setstring, "Set a string attribute on a principal",
+	set_string, setstr;
+
+request kadmin_delstring, "Delete a string attribute on a principal",
+	del_string, delstr;
+
 # list_requests is generic -- unrelated to Kerberos
 request	ss_list_requests, "List available requests.",
 	list_requests, lr, "?";

Modified: trunk/src/kadmin/server/kadm_rpc_svc.c
===================================================================
--- trunk/src/kadmin/server/kadm_rpc_svc.c	2011-09-21 16:28:54 UTC (rev 25214)
+++ trunk/src/kadmin/server/kadm_rpc_svc.c	2011-09-21 16:29:00 UTC (rev 25215)
@@ -213,6 +213,18 @@
 	  local = (char *(*)()) purgekeys_2_svc;
 	  break;
 
+     case GET_STRINGS:
+	  xdr_argument = xdr_gstrings_arg;
+	  xdr_result = xdr_gstrings_ret;
+	  local = (char *(*)()) get_strings_2_svc;
+	  break;
+
+     case SET_STRING:
+	  xdr_argument = xdr_sstring_arg;
+	  xdr_result = xdr_generic_ret;
+	  local = (char *(*)()) set_string_2_svc;
+	  break;
+
      default:
 	  krb5_klog_syslog(LOG_ERR, "Invalid KADM5 procedure number: %s, %d",
 		 inet_ntoa(rqstp->rq_xprt->xp_raddr.sin_addr),

Modified: trunk/src/kadmin/server/ovsec_kadmd.c
===================================================================
--- trunk/src/kadmin/server/ovsec_kadmd.c	2011-09-21 16:28:54 UTC (rev 25214)
+++ trunk/src/kadmin/server/ovsec_kadmd.c	2011-09-21 16:29:00 UTC (rev 25215)
@@ -746,7 +746,9 @@
         {19, "CHPASS_PRINCIPAL3"},
         {20, "CHRAND_PRINCIPAL3"},
         {21, "SETKEY_PRINCIPAL3"},
-        {22, "PURGEKEYS"}
+        {22, "PURGEKEYS"},
+        {23, "GET_STRINGS"},
+        {24, "SET_STRING"}
     };
 #define NPROCNAMES (sizeof (proc_names) / sizeof (struct procnames))
     OM_uint32 minor;

Modified: trunk/src/kadmin/server/server_stubs.c
===================================================================
--- trunk/src/kadmin/server/server_stubs.c	2011-09-21 16:28:54 UTC (rev 25214)
+++ trunk/src/kadmin/server/server_stubs.c	2011-09-21 16:29:00 UTC (rev 25215)
@@ -1604,6 +1604,118 @@
     return &ret;
 }
 
+gstrings_ret *
+get_strings_2_svc(gstrings_arg *arg, struct svc_req *rqstp)
+{
+    static gstrings_ret             ret;
+    char                            *prime_arg;
+    gss_buffer_desc                 client_name,
+        service_name;
+    OM_uint32                       minor_stat;
+    kadm5_server_handle_t           handle;
+    const char                      *errmsg = NULL;
+
+    xdr_free(xdr_gstrings_ret, &ret);
+
+    if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
+        goto exit_func;
+
+    if ((ret.code = check_handle((void *)handle)))
+        goto exit_func;
+
+    ret.api_version = handle->api_version;
+
+    if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
+        ret.code = KADM5_FAILURE;
+        goto exit_func;
+    }
+    if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
+        ret.code = KADM5_BAD_PRINCIPAL;
+        goto exit_func;
+    }
+
+    if (CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context,
+                                                       rqst2name(rqstp),
+                                                       ACL_LIST, NULL, NULL)) {
+        ret.code = KADM5_AUTH_LIST;
+        log_unauth("kadm5_get_strings", prime_arg,
+                   &client_name, &service_name, rqstp);
+    } else {
+        ret.code = kadm5_get_strings((void *)handle, arg->princ, &ret.strings,
+                                     &ret.count);
+        if (ret.code != 0)
+            errmsg = krb5_get_error_message(handle->context, ret.code);
+
+        log_done("kadm5_get_strings", prime_arg, errmsg,
+                 &client_name, &service_name, rqstp);
+
+        if (errmsg != NULL)
+            krb5_free_error_message(handle->context, errmsg);
+    }
+    free(prime_arg);
+    gss_release_buffer(&minor_stat, &client_name);
+    gss_release_buffer(&minor_stat, &service_name);
+exit_func:
+    free_server_handle(handle);
+    return &ret;
+}
+
+generic_ret *
+set_string_2_svc(sstring_arg *arg, struct svc_req *rqstp)
+{
+    static generic_ret              ret;
+    char                            *prime_arg;
+    gss_buffer_desc                 client_name,
+        service_name;
+    OM_uint32                       minor_stat;
+    kadm5_server_handle_t           handle;
+    const char                      *errmsg = NULL;
+
+    xdr_free(xdr_generic_ret, &ret);
+
+    if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
+        goto exit_func;
+
+    if ((ret.code = check_handle((void *)handle)))
+        goto exit_func;
+
+    ret.api_version = handle->api_version;
+
+    if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
+        ret.code = KADM5_FAILURE;
+        goto exit_func;
+    }
+    if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
+        ret.code = KADM5_BAD_PRINCIPAL;
+        goto exit_func;
+    }
+
+    if (CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context,
+                                                       rqst2name(rqstp),
+                                                       ACL_LIST, NULL, NULL)) {
+        ret.code = KADM5_AUTH_LIST;
+        log_unauth("kadm5_mod_strings", prime_arg,
+                   &client_name, &service_name, rqstp);
+    } else {
+        ret.code = kadm5_set_string((void *)handle, arg->princ, arg->key,
+                                    arg->value);
+        if (ret.code != 0)
+            errmsg = krb5_get_error_message(handle->context, ret.code);
+
+        log_done("kadm5_mod_strings", prime_arg, errmsg,
+                 &client_name, &service_name, rqstp);
+
+        if (errmsg != NULL)
+            krb5_free_error_message(handle->context, errmsg);
+    }
+    free(prime_arg);
+    gss_release_buffer(&minor_stat, &client_name);
+    gss_release_buffer(&minor_stat, &service_name);
+exit_func:
+    free_server_handle(handle);
+    return &ret;
+}
+
 generic_ret *init_2_svc(krb5_ui_4 *arg, struct svc_req *rqstp)
 {
     static generic_ret         ret;

Modified: trunk/src/lib/kadm5/admin.h
===================================================================
--- trunk/src/lib/kadm5/admin.h	2011-09-21 16:28:54 UTC (rev 25214)
+++ trunk/src/lib/kadm5/admin.h	2011-09-21 16:29:00 UTC (rev 25215)
@@ -513,6 +513,20 @@
                                krb5_principal principal,
                                int keepkvno);
 
+kadm5_ret_t    kadm5_get_strings(void *server_handle,
+                                 krb5_principal principal,
+                                 krb5_string_attr **strings_out,
+                                 int *count_out);
+
+kadm5_ret_t    kadm5_set_string(void *server_handle,
+                                krb5_principal principal,
+                                const char *key,
+                                const char *value);
+
+kadm5_ret_t    kadm5_free_strings(void *server_handle,
+                                  krb5_string_attr *strings,
+                                  int count);
+
 KADM5INT_END_DECLS
 
 #endif /* __KADM5_ADMIN_H__ */

Modified: trunk/src/lib/kadm5/admin_xdr.h
===================================================================
--- trunk/src/lib/kadm5/admin_xdr.h	2011-09-21 16:28:54 UTC (rev 25214)
+++ trunk/src/lib/kadm5/admin_xdr.h	2011-09-21 16:29:00 UTC (rev 25215)
@@ -56,6 +56,9 @@
 bool_t      xdr_gpols_ret(XDR *xdrs, gpols_ret *objp);
 bool_t      xdr_getprivs_ret(XDR *xdrs, getprivs_ret *objp);
 bool_t      xdr_purgekeys_arg(XDR *xdrs, purgekeys_arg *objp);
+bool_t      xdr_gstrings_arg(XDR *xdrs, gstrings_arg *objp);
+bool_t      xdr_gstrings_ret(XDR *xdrs, gstrings_ret *objp);
+bool_t      xdr_sstring_arg(XDR *xdrs, sstring_arg *objp);
 bool_t	    xdr_krb5_principal(XDR *xdrs, krb5_principal *objp);
 bool_t	    xdr_krb5_octet(XDR *xdrs, krb5_octet *objp);
 bool_t	    xdr_krb5_int32(XDR *xdrs, krb5_int32 *objp);
@@ -63,4 +66,5 @@
 bool_t      xdr_krb5_salttype(XDR *xdrs, krb5_int32 *objp);
 bool_t	    xdr_krb5_keyblock(XDR *xdrs, krb5_keyblock *objp);
 bool_t      xdr_krb5_key_data(XDR *xdrs, krb5_key_data *objp);
+bool_t      xdr_krb5_string_attr(XDR *xdrs, krb5_string_attr *objp);
 bool_t      xdr_osa_pw_hist_ent(XDR *xdrs, osa_pw_hist_ent *objp);

Modified: trunk/src/lib/kadm5/clnt/client_principal.c
===================================================================
--- trunk/src/lib/kadm5/clnt/client_principal.c	2011-09-21 16:28:54 UTC (rev 25214)
+++ trunk/src/lib/kadm5/clnt/client_principal.c	2011-09-21 16:29:00 UTC (rev 25215)
@@ -482,3 +482,51 @@
         eret();
     return r->code;
 }
+
+kadm5_ret_t
+kadm5_get_strings(void *server_handle, krb5_principal principal,
+                  krb5_string_attr **strings_out, int *count_out)
+{
+    gstrings_arg arg;
+    gstrings_ret *r;
+    kadm5_server_handle_t handle = server_handle;
+
+    *strings_out = NULL;
+    *count_out = 0;
+    CHECK_HANDLE(server_handle);
+    if (principal == NULL)
+        return EINVAL;
+
+    arg.princ = principal;
+    arg.api_version = handle->api_version;
+    r = get_strings_2(&arg, handle->clnt);
+    if (r == NULL)
+        eret();
+    if (r->code == 0) {
+        *strings_out = r->strings;
+        *count_out = r->count;
+    }
+    return r->code;
+}
+
+kadm5_ret_t
+kadm5_set_string(void *server_handle, krb5_principal principal,
+                 const char *key, const char *value)
+{
+    sstring_arg arg;
+    generic_ret *r;
+    kadm5_server_handle_t handle = server_handle;
+
+    CHECK_HANDLE(server_handle);
+    if (principal == NULL || key == NULL)
+        return EINVAL;
+
+    arg.princ = principal;
+    arg.key = (char *)key;
+    arg.value = (char *)value;
+    arg.api_version = handle->api_version;
+    r = set_string_2(&arg, handle->clnt);
+    if (r == NULL)
+        eret();
+    return r->code;
+}

Modified: trunk/src/lib/kadm5/clnt/client_rpc.c
===================================================================
--- trunk/src/lib/kadm5/clnt/client_rpc.c	2011-09-21 16:28:54 UTC (rev 25214)
+++ trunk/src/lib/kadm5/clnt/client_rpc.c	2011-09-21 16:29:00 UTC (rev 25215)
@@ -341,3 +341,33 @@
      }
      return (&clnt_res);
 }
+
+gstrings_ret *
+get_strings_2(gstrings_arg *argp, CLIENT *clnt)
+{
+     static gstrings_ret clnt_res;
+
+     memset(&clnt_res, 0, sizeof(clnt_res));
+     if (clnt_call(clnt, GET_STRINGS,
+		   (xdrproc_t) xdr_gstrings_arg, (caddr_t) argp,
+		   (xdrproc_t) xdr_gstrings_ret, (caddr_t) &clnt_res,
+		   TIMEOUT) != RPC_SUCCESS) {
+	  return (NULL);
+     }
+     return (&clnt_res);
+}
+
+generic_ret *
+set_string_2(sstring_arg *argp, CLIENT *clnt)
+{
+     static generic_ret clnt_res;
+
+     memset(&clnt_res, 0, sizeof(clnt_res));
+     if (clnt_call(clnt, SET_STRING,
+		   (xdrproc_t) xdr_sstring_arg, (caddr_t) argp,
+		   (xdrproc_t) xdr_generic_ret, (caddr_t) &clnt_res,
+		   TIMEOUT) != RPC_SUCCESS) {
+	  return (NULL);
+     }
+     return (&clnt_res);
+}

Modified: trunk/src/lib/kadm5/clnt/libkadm5clnt_mit.exports
===================================================================
--- trunk/src/lib/kadm5/clnt/libkadm5clnt_mit.exports	2011-09-21 16:28:54 UTC (rev 25214)
+++ trunk/src/lib/kadm5/clnt/libkadm5clnt_mit.exports	2011-09-21 16:29:00 UTC (rev 25215)
@@ -16,6 +16,7 @@
 kadm5_free_name_list
 kadm5_free_policy_ent
 kadm5_free_principal_ent
+kadm5_free_strings
 kadm5_get_admin_service_name
 kadm5_get_config_params
 kadm5_get_policies
@@ -23,6 +24,7 @@
 kadm5_get_principal
 kadm5_get_principals
 kadm5_get_privs
+kadm5_get_strings
 kadm5_init
 kadm5_init_anonymous
 kadm5_init_krb5_context
@@ -36,6 +38,7 @@
 kadm5_randkey_principal
 kadm5_randkey_principal_3
 kadm5_rename_principal
+kadm5_set_string
 kadm5_setkey_principal
 kadm5_setkey_principal_3
 kadm5_setv4key_principal

Modified: trunk/src/lib/kadm5/kadm_rpc.h
===================================================================
--- trunk/src/lib/kadm5/kadm_rpc.h	2011-09-21 16:28:54 UTC (rev 25214)
+++ trunk/src/lib/kadm5/kadm_rpc.h	2011-09-21 16:29:00 UTC (rev 25215)
@@ -207,6 +207,28 @@
 };
 typedef struct purgekeys_arg purgekeys_arg;
 
+struct gstrings_arg {
+	krb5_ui_4 api_version;
+	krb5_principal princ;
+};
+typedef struct gstrings_arg gstrings_arg;
+
+struct gstrings_ret {
+	krb5_ui_4 api_version;
+	kadm5_ret_t code;
+	krb5_string_attr *strings;
+	int count;
+};
+typedef struct gstrings_ret gstrings_ret;
+
+struct sstring_arg {
+	krb5_ui_4 api_version;
+	krb5_principal princ;
+	char *key;
+	char *value;
+};
+typedef struct sstring_arg sstring_arg;
+
 #define KADM 2112
 #define KADMVERS 2
 #define CREATE_PRINCIPAL 1
@@ -275,6 +297,12 @@
 #define PURGEKEYS 22
 extern  generic_ret * purgekeys_2(purgekeys_arg *, CLIENT *);
 extern  generic_ret * purgekeys_2_svc(purgekeys_arg *, struct svc_req *);
+#define GET_STRINGS 23
+extern  gstrings_ret * get_strings_2(gstrings_arg *, CLIENT *);
+extern  gstrings_ret * get_strings_2_svc(gstrings_arg *, struct svc_req *);
+#define SET_STRING 24
+extern  generic_ret * set_string_2(sstring_arg *, CLIENT *);
+extern  generic_ret * set_string_2_svc(sstring_arg *, struct svc_req *);
 
 extern bool_t xdr_cprinc_arg ();
 extern bool_t xdr_cprinc3_arg ();
@@ -312,6 +340,10 @@
 extern bool_t xdr_gpols_ret ();
 extern bool_t xdr_getprivs_ret ();
 extern bool_t xdr_purgekeys_arg ();
+extern bool_t xdr_gstrings_arg ();
+extern bool_t xdr_gstrings_ret ();
+extern bool_t xdr_sstring_arg ();
+extern bool_t xdr_krb5_string_attr ();
 
 
 #endif /* __KADM_RPC_H__ */

Modified: trunk/src/lib/kadm5/kadm_rpc_xdr.c
===================================================================
--- trunk/src/lib/kadm5/kadm_rpc_xdr.c	2011-09-21 16:28:54 UTC (rev 25214)
+++ trunk/src/lib/kadm5/kadm_rpc_xdr.c	2011-09-21 16:29:00 UTC (rev 25215)
@@ -972,6 +972,62 @@
 }
 
 bool_t
+xdr_gstrings_arg(XDR *xdrs, gstrings_arg *objp)
+{
+	if (!xdr_ui_4(xdrs, &objp->api_version)) {
+		return (FALSE);
+	}
+	if (!xdr_krb5_principal(xdrs, &objp->princ)) {
+		return (FALSE);
+	}
+
+	return (TRUE);
+}
+
+bool_t
+xdr_gstrings_ret(XDR *xdrs, gstrings_ret *objp)
+{
+	if (!xdr_ui_4(xdrs, &objp->api_version)) {
+		return (FALSE);
+	}
+	if (!xdr_kadm5_ret_t(xdrs, &objp->code)) {
+		return (FALSE);
+	}
+	if (objp->code == KADM5_OK) {
+		if (!xdr_int(xdrs, &objp->count)) {
+			return (FALSE);
+		}
+		if (!xdr_array(xdrs, (caddr_t *) &objp->strings,
+			       (unsigned int *) &objp->count, ~0,
+			       sizeof(krb5_string_attr),
+			       xdr_krb5_string_attr)) {
+			return (FALSE);
+		}
+	}
+
+	return (TRUE);
+}
+
+bool_t
+xdr_sstring_arg(XDR *xdrs, sstring_arg *objp)
+{
+	if (!xdr_ui_4(xdrs, &objp->api_version)) {
+		return (FALSE);
+	}
+	if (!xdr_krb5_principal(xdrs, &objp->princ)) {
+		return (FALSE);
+	}
+	if (!xdr_nullstring(xdrs, &objp->key)) {
+		return (FALSE);
+	}
+	if (!xdr_nullstring(xdrs, &objp->value)) {
+		return (FALSE);
+	}
+
+	return (TRUE);
+}
+
+bool_t
 xdr_krb5_principal(XDR *xdrs, krb5_principal *objp)
 {
     int	    ret;
@@ -1063,3 +1119,16 @@
       return FALSE;
    return TRUE;
 }
+
+bool_t
+xdr_krb5_string_attr(XDR *xdrs, krb5_string_attr *objp)
+{
+	if (!xdr_nullstring(xdrs, &objp->key))
+		return FALSE;
+	if (!xdr_nullstring(xdrs, &objp->value))
+		return FALSE;
+	if (xdrs->x_op == XDR_DECODE &&
+	    (objp->key == NULL || objp->value == NULL))
+		return FALSE;
+	return TRUE;
+}

Modified: trunk/src/lib/kadm5/misc_free.c
===================================================================
--- trunk/src/lib/kadm5/misc_free.c	2011-09-21 16:28:54 UTC (rev 25214)
+++ trunk/src/lib/kadm5/misc_free.c	2011-09-21 16:29:00 UTC (rev 25215)
@@ -89,3 +89,22 @@
     }
     return KADM5_OK;
 }
+
+kadm5_ret_t
+kadm5_free_strings(void *server_handle, krb5_string_attr *strings,
+                   int count)
+{
+    int i;
+
+    _KADM5_CHECK_HANDLE(server_handle);
+
+    if (!strings)
+        return KADM5_OK;
+
+    for (i = 0; i < count; i++) {
+        free(strings[i].key);
+        free(strings[i].value);
+    }
+    free(strings);
+    return KADM5_OK;
+}

Modified: trunk/src/lib/kadm5/srv/libkadm5srv_mit.exports
===================================================================
--- trunk/src/lib/kadm5/srv/libkadm5srv_mit.exports	2011-09-21 16:28:54 UTC (rev 25214)
+++ trunk/src/lib/kadm5/srv/libkadm5srv_mit.exports	2011-09-21 16:29:00 UTC (rev 25215)
@@ -26,6 +26,7 @@
 kadm5_free_name_list
 kadm5_free_policy_ent
 kadm5_free_principal_ent
+kadm5_free_strings
 kadm5_get_config_params
 kadm5_get_policies
 kadm5_get_policy
@@ -33,6 +34,7 @@
 kadm5_get_principal_keys
 kadm5_get_principals
 kadm5_get_privs
+kadm5_get_strings
 kadm5_init
 kadm5_init_anonymous
 kadm5_init_krb5_context
@@ -47,6 +49,7 @@
 kadm5_randkey_principal
 kadm5_randkey_principal_3
 kadm5_rename_principal
+kadm5_set_string
 kadm5_setkey_principal
 kadm5_setkey_principal_3
 kadm5_setv4key_principal
@@ -105,6 +108,8 @@
 xdr_gprinc_ret
 xdr_gprincs_arg
 xdr_gprincs_ret
+xdr_gstrings_arg
+xdr_gstrings_ret
 xdr_kadm5_policy_ent_rec
 xdr_kadm5_principal_ent_rec
 xdr_kadm5_ret_t
@@ -120,6 +125,7 @@
 xdr_krb5_octet
 xdr_krb5_principal
 xdr_krb5_salttype
+xdr_krb5_string_attr
 xdr_krb5_timestamp
 xdr_krb5_tl_data
 xdr_krb5_ui_2
@@ -135,5 +141,6 @@
 xdr_setkey3_arg
 xdr_setkey_arg
 xdr_setv4key_arg
+xdr_sstring_arg
 xdr_ui_4
 kadm5_init_iprop

Modified: trunk/src/lib/kadm5/srv/svr_principal.c
===================================================================
--- trunk/src/lib/kadm5/srv/svr_principal.c	2011-09-21 16:28:54 UTC (rev 25214)
+++ trunk/src/lib/kadm5/srv/svr_principal.c	2011-09-21 16:29:00 UTC (rev 25215)
@@ -2307,3 +2307,55 @@
     kdb_free_entry(handle, kdb, &adb);
     return ret;
 }
+
+kadm5_ret_t
+kadm5_get_strings(void *server_handle, krb5_principal principal,
+                  krb5_string_attr **strings_out, int *count_out)
+{
+    kadm5_server_handle_t handle = server_handle;
+    kadm5_ret_t ret;
+    krb5_db_entry *kdb = NULL;
+
+    *strings_out = NULL;
+    *count_out = 0;
+    CHECK_HANDLE(server_handle);
+    if (principal == NULL)
+        return EINVAL;
+
+    ret = kdb_get_entry(handle, principal, &kdb, NULL);
+    if (ret)
+        return ret;
+
+    ret = krb5_dbe_get_strings(handle->context, kdb, strings_out, count_out);
+    kdb_free_entry(handle, kdb, NULL);
+    return ret;
+}
+
+kadm5_ret_t
+kadm5_set_string(void *server_handle, krb5_principal principal,
+                 const char *key, const char *value)
+{
+    kadm5_server_handle_t handle = server_handle;
+    kadm5_ret_t ret;
+    krb5_db_entry *kdb;
+    osa_princ_ent_rec adb;
+
+    CHECK_HANDLE(server_handle);
+    if (principal == NULL || key == NULL)
+        return EINVAL;
+
+    ret = kdb_get_entry(handle, principal, &kdb, &adb);
+    if (ret)
+        return ret;
+
+    ret = krb5_dbe_set_string(handle->context, kdb, key, value);
+    if (ret)
+        goto done;
+
+    kdb->mask = KADM5_TL_DATA;
+    ret = kdb_put_entry(handle, kdb, &adb);
+
+done:
+    kdb_free_entry(handle, kdb, &adb);
+    return ret;
+}

Modified: trunk/src/tests/Makefile.in
===================================================================
--- trunk/src/tests/Makefile.in	2011-09-21 16:28:54 UTC (rev 25214)
+++ trunk/src/tests/Makefile.in	2011-09-21 16:29:00 UTC (rev 25215)
@@ -69,6 +69,7 @@
 	$(RUNPYTEST) $(srcdir)/t_renew.py $(PYTESTFLAGS)
 	$(RUNPYTEST) $(srcdir)/t_renprinc.py $(PYTESTFLAGS)
 	$(RUNPYTEST) $(srcdir)/t_cccol.py $(PYTESTFLAGS)
+	$(RUNPYTEST) $(srcdir)/t_stringattr.py $(PYTESTFLAGS)
 
 clean::
 	$(RM) kdc.conf

Added: trunk/src/tests/t_stringattr.py
===================================================================
--- trunk/src/tests/t_stringattr.py	                        (rev 0)
+++ trunk/src/tests/t_stringattr.py	2011-09-21 16:29:00 UTC (rev 25215)
@@ -0,0 +1,56 @@
+# Copyright (C) 2011 by the Massachusetts Institute of Technology.
+# All rights reserved.
+
+# Export of this software from the United States of America may
+#   require a specific license from the United States Government.
+#   It is the responsibility of any person or organization contemplating
+#   export to obtain such a license before exporting.
+#
+# WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+# distribute this software and its documentation for any purpose and
+# without fee is hereby granted, provided that the above copyright
+# notice appear in all copies and that both that copyright notice and
+# this permission notice appear in supporting documentation, and that
+# the name of M.I.T. not be used in advertising or publicity pertaining
+# to distribution of the software without specific, written prior
+# permission.  Furthermore if you modify this software you must label
+# your software as modified software and not distribute it in such a
+# fashion that it might be confused with the original M.I.T. software.
+# M.I.T. makes no representations about the suitability of
+# this software for any purpose.  It is provided "as is" without express
+# or implied warranty.
+
+#!/usr/bin/python
+from k5test import *
+
+def run_kadmin(query):
+    global realm
+    return realm.run_as_master([kadmin, '-c', realm.ccache, '-q', query])
+
+realm = K5Realm(create_host=False, get_creds=False)
+
+realm.kinit(realm.admin_princ, password('admin'), flags=['-S', 'kadmin/admin'])
+
+output = run_kadmin('getstrs user')
+if '(No string attributes.)' not in output:
+    fail('Empty attribute query')
+
+output = run_kadmin('setstr user attr1 value1')
+if 'Attribute set for principal' not in output:
+    fail('Setting attr1')
+output = run_kadmin('setstr user attr2 value2')
+if 'Attribute set for principal' not in output:
+    fail('Setting attr2')
+output = run_kadmin('delstr user attr1')
+if 'Attribute removed from principal' not in output:
+    fail('Deleting attr1')
+output = run_kadmin('setstr user attr3 value3')
+if 'Attribute set for principal' not in output:
+    fail('Setting attr3')
+
+output = run_kadmin('getstrs user')
+if 'attr2: value2' not in output or 'attr3: value3' not in output or \
+        'attr1:' in output:
+    fail('Final attribute query')
+
+success('KDB string attributes.')




More information about the cvs-krb5 mailing list