|
|
f762fea |
diff --git a/configure.ac b/configure.ac
|
|
|
f762fea |
index 518b6d8..d90a88f 100644
|
|
|
f762fea |
--- a/configure.ac
|
|
|
f762fea |
+++ b/configure.ac
|
|
|
f762fea |
@@ -425,6 +425,8 @@ AC_CONFIG_FILES([
|
|
|
f762fea |
tools/nlmtest/Makefile
|
|
|
f762fea |
tools/rpcdebug/Makefile
|
|
|
f762fea |
tools/rpcgen/Makefile
|
|
|
f762fea |
+ tools/mountstats/Makefile
|
|
|
f762fea |
+ tools/nfs-iostat/Makefile
|
|
|
f762fea |
utils/Makefile
|
|
|
f762fea |
utils/exportfs/Makefile
|
|
|
f762fea |
utils/gssd/Makefile
|
|
|
f762fea |
diff --git a/support/export/client.c b/support/export/client.c
|
|
|
f762fea |
index 5e937b0..6a25928 100644
|
|
|
f762fea |
--- a/support/export/client.c
|
|
|
f762fea |
+++ b/support/export/client.c
|
|
|
f762fea |
@@ -32,11 +32,26 @@ extern int innetgr(char *netgr, char *host, char *, char *);
|
|
|
f762fea |
static char *add_name(char *old, const char *add);
|
|
|
f762fea |
static void client_init(nfs_client *clp, const char *hname,
|
|
|
f762fea |
struct hostent *hp);
|
|
|
f762fea |
-static int client_checkaddr(nfs_client *clp, struct in_addr addr);
|
|
|
f762fea |
|
|
|
f762fea |
nfs_client *clientlist[MCL_MAXTYPES] = { NULL, };
|
|
|
f762fea |
|
|
|
f762fea |
|
|
|
f762fea |
+static void
|
|
|
f762fea |
+init_addrlist(nfs_client *clp, const struct hostent *hp)
|
|
|
f762fea |
+{
|
|
|
f762fea |
+ char **ap;
|
|
|
f762fea |
+ int i;
|
|
|
f762fea |
+
|
|
|
f762fea |
+ if (hp == NULL)
|
|
|
f762fea |
+ return;
|
|
|
f762fea |
+
|
|
|
f762fea |
+ ap = hp->h_addr_list;
|
|
|
f762fea |
+ for (i = 0; *ap != NULL && i < NFSCLNT_ADDRMAX; i++, ap++)
|
|
|
f762fea |
+ clp->m_addrlist[i] = *(struct in_addr *)*ap;
|
|
|
f762fea |
+
|
|
|
f762fea |
+ clp->m_naddr = i;
|
|
|
f762fea |
+}
|
|
|
f762fea |
+
|
|
|
f762fea |
/* if canonical is set, then we *know* this is already a canonical name
|
|
|
f762fea |
* so hostname lookup is avoided.
|
|
|
f762fea |
* This is used when reading /proc/fs/nfs/exports
|
|
|
f762fea |
@@ -97,14 +112,8 @@ client_lookup(char *hname, int canonical)
|
|
|
f762fea |
client_add(clp);
|
|
|
f762fea |
}
|
|
|
f762fea |
|
|
|
f762fea |
- if (htype == MCL_FQDN && clp->m_naddr == 0 && hp != NULL) {
|
|
|
f762fea |
- char **ap = hp->h_addr_list;
|
|
|
f762fea |
- int i;
|
|
|
f762fea |
-
|
|
|
f762fea |
- for (i = 0; *ap && i < NFSCLNT_ADDRMAX; i++, ap++)
|
|
|
f762fea |
- clp->m_addrlist[i] = *(struct in_addr *)*ap;
|
|
|
f762fea |
- clp->m_naddr = i;
|
|
|
f762fea |
- }
|
|
|
f762fea |
+ if (htype == MCL_FQDN && clp->m_naddr == 0)
|
|
|
f762fea |
+ init_addrlist(clp, hp);
|
|
|
f762fea |
|
|
|
f762fea |
if (hp)
|
|
|
f762fea |
free (hp);
|
|
|
f762fea |
@@ -138,6 +147,7 @@ client_init(nfs_client *clp, const char *hname, struct hostent *hp)
|
|
|
f762fea |
|
|
|
f762fea |
clp->m_exported = 0;
|
|
|
f762fea |
clp->m_count = 0;
|
|
|
f762fea |
+ clp->m_naddr = 0;
|
|
|
f762fea |
|
|
|
f762fea |
if (clp->m_type == MCL_SUBNETWORK) {
|
|
|
f762fea |
char *cp = strchr(clp->m_hostname, '/');
|
|
|
f762fea |
@@ -161,18 +171,10 @@ client_init(nfs_client *clp, const char *hname, struct hostent *hp)
|
|
|
f762fea |
}
|
|
|
f762fea |
}
|
|
|
f762fea |
*cp = '/';
|
|
|
f762fea |
- clp->m_naddr = 0;
|
|
|
f762fea |
- } else if (!hp) {
|
|
|
f762fea |
- clp->m_naddr = 0;
|
|
|
f762fea |
- } else {
|
|
|
f762fea |
- char **ap = hp->h_addr_list;
|
|
|
f762fea |
- int i;
|
|
|
f762fea |
-
|
|
|
f762fea |
- for (i = 0; *ap && i < NFSCLNT_ADDRMAX; i++, ap++) {
|
|
|
f762fea |
- clp->m_addrlist[i] = *(struct in_addr *)*ap;
|
|
|
f762fea |
- }
|
|
|
f762fea |
- clp->m_naddr = i;
|
|
|
f762fea |
+ return;
|
|
|
f762fea |
}
|
|
|
f762fea |
+
|
|
|
f762fea |
+ init_addrlist(clp, hp);
|
|
|
f762fea |
}
|
|
|
f762fea |
|
|
|
f762fea |
void
|
|
|
f762fea |
@@ -329,101 +331,158 @@ add_name(char *old, const char *add)
|
|
|
f762fea |
}
|
|
|
f762fea |
|
|
|
f762fea |
/*
|
|
|
f762fea |
- * Match a host (given its hostent record) to a client record. This
|
|
|
f762fea |
- * is usually called from mountd.
|
|
|
f762fea |
+ * Check each address listed in @hp against each address
|
|
|
f762fea |
+ * stored in @clp. Return 1 if a match is found, otherwise
|
|
|
f762fea |
+ * zero.
|
|
|
f762fea |
*/
|
|
|
f762fea |
-int
|
|
|
f762fea |
-client_check(nfs_client *clp, struct hostent *hp)
|
|
|
f762fea |
+static int
|
|
|
f762fea |
+check_fqdn(const nfs_client *clp, const struct hostent *hp)
|
|
|
f762fea |
{
|
|
|
f762fea |
- char *hname = (char *) hp->h_name;
|
|
|
f762fea |
- char *cname = clp->m_hostname;
|
|
|
f762fea |
- char **ap;
|
|
|
f762fea |
+ struct in_addr addr;
|
|
|
f762fea |
+ char **ap;
|
|
|
f762fea |
+ int i;
|
|
|
f762fea |
|
|
|
f762fea |
- switch (clp->m_type) {
|
|
|
f762fea |
- case MCL_FQDN:
|
|
|
f762fea |
- case MCL_SUBNETWORK:
|
|
|
f762fea |
- for (ap = hp->h_addr_list; *ap; ap++) {
|
|
|
f762fea |
- if (client_checkaddr(clp, *(struct in_addr *) *ap))
|
|
|
f762fea |
- return 1;
|
|
|
f762fea |
- }
|
|
|
f762fea |
- return 0;
|
|
|
f762fea |
- case MCL_WILDCARD:
|
|
|
f762fea |
- if (wildmat(hname, cname))
|
|
|
f762fea |
- return 1;
|
|
|
f762fea |
- else {
|
|
|
f762fea |
- for (ap = hp->h_aliases; *ap; ap++)
|
|
|
f762fea |
- if (wildmat(*ap, cname))
|
|
|
f762fea |
- return 1;
|
|
|
f762fea |
- }
|
|
|
f762fea |
- return 0;
|
|
|
f762fea |
- case MCL_NETGROUP:
|
|
|
f762fea |
-#ifdef HAVE_INNETGR
|
|
|
f762fea |
- {
|
|
|
f762fea |
- char *dot;
|
|
|
f762fea |
- int match, i;
|
|
|
f762fea |
- struct hostent *nhp = NULL;
|
|
|
f762fea |
- struct sockaddr_in addr;
|
|
|
f762fea |
-
|
|
|
f762fea |
- /* First, try to match the hostname without
|
|
|
f762fea |
- * splitting off the domain */
|
|
|
f762fea |
- if (innetgr(cname+1, hname, NULL, NULL))
|
|
|
f762fea |
+ for (ap = hp->h_addr_list; *ap; ap++) {
|
|
|
f762fea |
+ addr = *(struct in_addr *)*ap;
|
|
|
f762fea |
+
|
|
|
f762fea |
+ for (i = 0; i < clp->m_naddr; i++)
|
|
|
f762fea |
+ if (clp->m_addrlist[i].s_addr == addr.s_addr)
|
|
|
f762fea |
return 1;
|
|
|
f762fea |
+ }
|
|
|
f762fea |
+ return 0;
|
|
|
f762fea |
+}
|
|
|
f762fea |
|
|
|
f762fea |
- /* try the aliases as well */
|
|
|
f762fea |
- for (i = 0; hp->h_aliases[i]; i++) {
|
|
|
f762fea |
- if (innetgr(cname+1, hp->h_aliases[i], NULL, NULL))
|
|
|
f762fea |
- return 1;
|
|
|
f762fea |
- }
|
|
|
f762fea |
+/*
|
|
|
f762fea |
+ * Check each address listed in @hp against the subnetwork or
|
|
|
f762fea |
+ * host address stored in @clp. Return 1 if an address in @hp
|
|
|
f762fea |
+ * matches the host address stored in @clp, otherwise zero.
|
|
|
f762fea |
+ */
|
|
|
f762fea |
+static int
|
|
|
f762fea |
+check_subnetwork(const nfs_client *clp, const struct hostent *hp)
|
|
|
f762fea |
+{
|
|
|
f762fea |
+ struct in_addr addr;
|
|
|
f762fea |
+ char **ap;
|
|
|
f762fea |
|
|
|
f762fea |
- /* If hname is ip address convert to FQDN */
|
|
|
f762fea |
- if (inet_aton(hname, &addr.sin_addr) &&
|
|
|
f762fea |
- (nhp = gethostbyaddr((const char *)&(addr.sin_addr),
|
|
|
f762fea |
- sizeof(addr.sin_addr), AF_INET))) {
|
|
|
f762fea |
- hname = (char *)nhp->h_name;
|
|
|
f762fea |
- if (innetgr(cname+1, hname, NULL, NULL))
|
|
|
f762fea |
- return 1;
|
|
|
f762fea |
- }
|
|
|
f762fea |
+ for (ap = hp->h_addr_list; *ap; ap++) {
|
|
|
f762fea |
+ addr = *(struct in_addr *)*ap;
|
|
|
f762fea |
|
|
|
f762fea |
- /* Okay, strip off the domain (if we have one) */
|
|
|
f762fea |
- if ((dot = strchr(hname, '.')) == NULL)
|
|
|
f762fea |
- return 0;
|
|
|
f762fea |
+ if (!((clp->m_addrlist[0].s_addr ^ addr.s_addr) &
|
|
|
f762fea |
+ clp->m_addrlist[1].s_addr))
|
|
|
f762fea |
+ return 1;
|
|
|
f762fea |
+ }
|
|
|
f762fea |
+ return 0;
|
|
|
f762fea |
+}
|
|
|
f762fea |
|
|
|
f762fea |
- *dot = '\0';
|
|
|
f762fea |
- match = innetgr(cname+1, hname, NULL, NULL);
|
|
|
f762fea |
- *dot = '.';
|
|
|
f762fea |
+/*
|
|
|
f762fea |
+ * Check if a wildcard nfs_client record matches the canonical name
|
|
|
f762fea |
+ * or the aliases of a host. Return 1 if a match is found, otherwise
|
|
|
f762fea |
+ * zero.
|
|
|
f762fea |
+ */
|
|
|
f762fea |
+static int
|
|
|
f762fea |
+check_wildcard(const nfs_client *clp, const struct hostent *hp)
|
|
|
f762fea |
+{
|
|
|
f762fea |
+ char *cname = clp->m_hostname;
|
|
|
f762fea |
+ char *hname = hp->h_name;
|
|
|
f762fea |
+ char **ap;
|
|
|
f762fea |
|
|
|
f762fea |
- return match;
|
|
|
f762fea |
- }
|
|
|
f762fea |
-#else
|
|
|
f762fea |
- return 0;
|
|
|
f762fea |
-#endif
|
|
|
f762fea |
- case MCL_ANONYMOUS:
|
|
|
f762fea |
+ if (wildmat(hname, cname))
|
|
|
f762fea |
return 1;
|
|
|
f762fea |
- case MCL_GSS:
|
|
|
f762fea |
- return 0;
|
|
|
f762fea |
- default:
|
|
|
f762fea |
- xlog(L_FATAL, "internal: bad client type %d", clp->m_type);
|
|
|
f762fea |
+
|
|
|
f762fea |
+ /* See if hname aliases listed in /etc/hosts or nis[+]
|
|
|
f762fea |
+ * match the requested wildcard */
|
|
|
f762fea |
+ for (ap = hp->h_aliases; *ap; ap++) {
|
|
|
f762fea |
+ if (wildmat(*ap, cname))
|
|
|
f762fea |
+ return 1;
|
|
|
f762fea |
}
|
|
|
f762fea |
|
|
|
f762fea |
return 0;
|
|
|
f762fea |
}
|
|
|
f762fea |
|
|
|
f762fea |
+/*
|
|
|
f762fea |
+ * Check if @hp's hostname or aliases fall in a given netgroup.
|
|
|
f762fea |
+ * Return 1 if @hp represents a host in the netgroup, otherwise zero.
|
|
|
f762fea |
+ */
|
|
|
f762fea |
+#ifdef HAVE_INNETGR
|
|
|
f762fea |
+static int
|
|
|
f762fea |
+check_netgroup(const nfs_client *clp, const struct hostent *hp)
|
|
|
f762fea |
+{
|
|
|
f762fea |
+ const char *netgroup = clp->m_hostname + 1;
|
|
|
f762fea |
+ const char *hname = hp->h_name;
|
|
|
f762fea |
+ struct hostent *nhp = NULL;
|
|
|
f762fea |
+ struct sockaddr_in addr;
|
|
|
f762fea |
+ int match, i;
|
|
|
f762fea |
+ char *dot;
|
|
|
f762fea |
+
|
|
|
f762fea |
+ /* First, try to match the hostname without
|
|
|
f762fea |
+ * splitting off the domain */
|
|
|
f762fea |
+ if (innetgr(netgroup, hname, NULL, NULL))
|
|
|
f762fea |
+ return 1;
|
|
|
f762fea |
+
|
|
|
f762fea |
+ /* See if hname aliases listed in /etc/hosts or nis[+]
|
|
|
f762fea |
+ * match the requested netgroup */
|
|
|
f762fea |
+ for (i = 0; hp->h_aliases[i]; i++) {
|
|
|
f762fea |
+ if (innetgr(netgroup, hp->h_aliases[i], NULL, NULL))
|
|
|
f762fea |
+ return 1;
|
|
|
f762fea |
+ }
|
|
|
f762fea |
+
|
|
|
f762fea |
+ /* If hname is ip address convert to FQDN */
|
|
|
f762fea |
+ if (inet_aton(hname, &addr.sin_addr) &&
|
|
|
f762fea |
+ (nhp = gethostbyaddr((const char *)&(addr.sin_addr),
|
|
|
f762fea |
+ sizeof(addr.sin_addr), AF_INET))) {
|
|
|
f762fea |
+ hname = nhp->h_name;
|
|
|
f762fea |
+ if (innetgr(netgroup, hname, NULL, NULL))
|
|
|
f762fea |
+ return 1;
|
|
|
f762fea |
+ }
|
|
|
f762fea |
+
|
|
|
f762fea |
+ /* Okay, strip off the domain (if we have one) */
|
|
|
f762fea |
+ dot = strchr(hname, '.');
|
|
|
f762fea |
+ if (dot == NULL)
|
|
|
f762fea |
+ return 0;
|
|
|
f762fea |
+
|
|
|
f762fea |
+ *dot = '\0';
|
|
|
f762fea |
+ match = innetgr(netgroup, hname, NULL, NULL);
|
|
|
f762fea |
+ *dot = '.';
|
|
|
f762fea |
+
|
|
|
f762fea |
+ return match;
|
|
|
f762fea |
+}
|
|
|
f762fea |
+#else /* !HAVE_INNETGR */
|
|
|
f762fea |
static int
|
|
|
f762fea |
-client_checkaddr(nfs_client *clp, struct in_addr addr)
|
|
|
f762fea |
+check_netgroup(__attribute__((unused)) const nfs_client *clp,
|
|
|
f762fea |
+ __attribute__((unused)) const struct hostent *hp)
|
|
|
f762fea |
{
|
|
|
f762fea |
- int i;
|
|
|
f762fea |
+ return 0;
|
|
|
f762fea |
+}
|
|
|
f762fea |
+#endif /* !HAVE_INNETGR */
|
|
|
f762fea |
|
|
|
f762fea |
+/**
|
|
|
f762fea |
+ * client_check - check if IP address information matches a cached nfs_client
|
|
|
f762fea |
+ * @clp: pointer to a cached nfs_client record
|
|
|
f762fea |
+ * @hp: pointer to hostent containing host IP information
|
|
|
f762fea |
+ *
|
|
|
f762fea |
+ * Returns 1 if the address information matches the cached nfs_client,
|
|
|
f762fea |
+ * otherwise zero.
|
|
|
f762fea |
+ */
|
|
|
f762fea |
+int
|
|
|
f762fea |
+client_check(nfs_client *clp, struct hostent *hp)
|
|
|
f762fea |
+{
|
|
|
f762fea |
switch (clp->m_type) {
|
|
|
f762fea |
case MCL_FQDN:
|
|
|
f762fea |
- for (i = 0; i < clp->m_naddr; i++) {
|
|
|
f762fea |
- if (clp->m_addrlist[i].s_addr == addr.s_addr)
|
|
|
f762fea |
- return 1;
|
|
|
f762fea |
- }
|
|
|
f762fea |
- return 0;
|
|
|
f762fea |
+ return check_fqdn(clp, hp);
|
|
|
f762fea |
case MCL_SUBNETWORK:
|
|
|
f762fea |
- return !((clp->m_addrlist[0].s_addr ^ addr.s_addr)
|
|
|
f762fea |
- & clp->m_addrlist[1].s_addr);
|
|
|
f762fea |
+ return check_subnetwork(clp, hp);
|
|
|
f762fea |
+ case MCL_WILDCARD:
|
|
|
f762fea |
+ return check_wildcard(clp, hp);
|
|
|
f762fea |
+ case MCL_NETGROUP:
|
|
|
f762fea |
+ return check_netgroup(clp, hp);
|
|
|
f762fea |
+ case MCL_ANONYMOUS:
|
|
|
f762fea |
+ return 1;
|
|
|
f762fea |
+ case MCL_GSS:
|
|
|
f762fea |
+ return 0;
|
|
|
f762fea |
+ default:
|
|
|
f762fea |
+ xlog(D_GENERAL, "%s: unrecognized client type: %d",
|
|
|
f762fea |
+ __func__, clp->m_type);
|
|
|
f762fea |
}
|
|
|
f762fea |
+
|
|
|
f762fea |
return 0;
|
|
|
f762fea |
}
|
|
|
f762fea |
|
|
|
f762fea |
diff --git a/support/export/export.c b/support/export/export.c
|
|
|
f762fea |
index 42e78f6..3e4da69 100644
|
|
|
f762fea |
--- a/support/export/export.c
|
|
|
f762fea |
+++ b/support/export/export.c
|
|
|
f762fea |
@@ -28,6 +28,18 @@ static int export_check(nfs_export *, struct hostent *, char *);
|
|
|
f762fea |
static nfs_export *
|
|
|
f762fea |
export_allowed_internal(struct hostent *hp, char *path);
|
|
|
f762fea |
|
|
|
f762fea |
+static void
|
|
|
f762fea |
+export_free(nfs_export *exp)
|
|
|
f762fea |
+{
|
|
|
f762fea |
+ xfree(exp->m_export.e_squids);
|
|
|
f762fea |
+ xfree(exp->m_export.e_sqgids);
|
|
|
f762fea |
+ free(exp->m_export.e_mountpoint);
|
|
|
f762fea |
+ free(exp->m_export.e_fslocdata);
|
|
|
f762fea |
+
|
|
|
f762fea |
+ xfree(exp->m_export.e_hostname);
|
|
|
f762fea |
+ xfree(exp);
|
|
|
f762fea |
+}
|
|
|
f762fea |
+
|
|
|
f762fea |
static void warn_duplicated_exports(nfs_export *exp, struct exportent *eep)
|
|
|
f762fea |
{
|
|
|
f762fea |
if (exp->m_export.e_flags != eep->e_flags) {
|
|
|
f762fea |
@@ -117,6 +129,10 @@ export_dup(nfs_export *exp, struct hostent *hp)
|
|
|
f762fea |
if (exp->m_export.e_hostname)
|
|
|
f762fea |
new->m_export.e_hostname = xstrdup(exp->m_export.e_hostname);
|
|
|
f762fea |
clp = client_dup(exp->m_client, hp);
|
|
|
f762fea |
+ if (clp == NULL) {
|
|
|
f762fea |
+ export_free(new);
|
|
|
f762fea |
+ return NULL;
|
|
|
f762fea |
+ }
|
|
|
f762fea |
clp->m_count++;
|
|
|
f762fea |
new->m_client = clp;
|
|
|
f762fea |
new->m_mayexport = exp->m_mayexport;
|
|
|
f762fea |
@@ -260,6 +276,10 @@ export_check(nfs_export *exp, struct hostent *hp, char *path)
|
|
|
f762fea |
return client_check(exp->m_client, hp);
|
|
|
f762fea |
}
|
|
|
f762fea |
|
|
|
f762fea |
+/**
|
|
|
f762fea |
+ * export_freeall - deallocate all nfs_export records
|
|
|
f762fea |
+ *
|
|
|
f762fea |
+ */
|
|
|
f762fea |
void
|
|
|
f762fea |
export_freeall(void)
|
|
|
f762fea |
{
|
|
|
f762fea |
@@ -270,16 +290,7 @@ export_freeall(void)
|
|
|
f762fea |
for (exp = exportlist[i].p_head; exp; exp = nxt) {
|
|
|
f762fea |
nxt = exp->m_next;
|
|
|
f762fea |
client_release(exp->m_client);
|
|
|
f762fea |
- if (exp->m_export.e_squids)
|
|
|
f762fea |
- xfree(exp->m_export.e_squids);
|
|
|
f762fea |
- if (exp->m_export.e_sqgids)
|
|
|
f762fea |
- xfree(exp->m_export.e_sqgids);
|
|
|
f762fea |
- if (exp->m_export.e_mountpoint)
|
|
|
f762fea |
- free(exp->m_export.e_mountpoint);
|
|
|
f762fea |
- if (exp->m_export.e_fslocdata)
|
|
|
f762fea |
- free(exp->m_export.e_fslocdata);
|
|
|
f762fea |
- xfree(exp->m_export.e_hostname);
|
|
|
f762fea |
- xfree(exp);
|
|
|
f762fea |
+ export_free(exp);
|
|
|
f762fea |
}
|
|
|
f762fea |
for (j = 0; j < HASH_TABLE_SIZE; j++) {
|
|
|
f762fea |
exportlist[i].entries[j].p_first = NULL;
|
|
|
f762fea |
diff --git a/support/include/nfslib.h b/support/include/nfslib.h
|
|
|
f762fea |
index 537a31e..e44cf8f 100644
|
|
|
f762fea |
--- a/support/include/nfslib.h
|
|
|
f762fea |
+++ b/support/include/nfslib.h
|
|
|
f762fea |
@@ -152,6 +152,8 @@ void qword_addhex(char **bpp, int *lp, char *buf, int blen);
|
|
|
f762fea |
void qword_addint(char **bpp, int *lp, int n);
|
|
|
f762fea |
void qword_adduint(char **bpp, int *lp, unsigned int n);
|
|
|
f762fea |
void qword_addeol(char **bpp, int *lp);
|
|
|
f762fea |
+int qword_get_uint(char **bpp, unsigned int *anint);
|
|
|
f762fea |
+void qword_printuint(FILE *f, unsigned int num);
|
|
|
f762fea |
|
|
|
f762fea |
void closeall(int min);
|
|
|
f762fea |
|
|
|
f762fea |
diff --git a/support/nfs/cacheio.c b/support/nfs/cacheio.c
|
|
|
f762fea |
index 0587ecb..55fa45d 100644
|
|
|
f762fea |
--- a/support/nfs/cacheio.c
|
|
|
f762fea |
+++ b/support/nfs/cacheio.c
|
|
|
f762fea |
@@ -241,7 +241,7 @@ int qword_get_int(char **bpp, int *anint)
|
|
|
f762fea |
return 0;
|
|
|
f762fea |
}
|
|
|
f762fea |
|
|
|
f762fea |
-int qword_get_uint(char *bpp, unsigned int *anint)
|
|
|
f762fea |
+int qword_get_uint(char **bpp, unsigned int *anint)
|
|
|
f762fea |
{
|
|
|
f762fea |
char buf[50];
|
|
|
f762fea |
char *ep;
|
|
|
f762fea |
diff --git a/tests/t0001-statd-basic-mon-unmon.sh b/tests/t0001-statd-basic-mon-unmon.sh
|
|
|
f762fea |
old mode 100644
|
|
|
f762fea |
new mode 100755
|
|
|
f762fea |
diff --git a/tools/Makefile.am b/tools/Makefile.am
|
|
|
f762fea |
index db15346..f2ce282 100644
|
|
|
f762fea |
--- a/tools/Makefile.am
|
|
|
f762fea |
+++ b/tools/Makefile.am
|
|
|
f762fea |
@@ -6,6 +6,6 @@ if CONFIG_RPCGEN
|
|
|
f762fea |
OPTDIRS += rpcgen
|
|
|
f762fea |
endif
|
|
|
f762fea |
|
|
|
f762fea |
-SUBDIRS = locktest rpcdebug nlmtest $(OPTDIRS)
|
|
|
f762fea |
+SUBDIRS = locktest rpcdebug nlmtest mountstats nfs-iostat $(OPTDIRS)
|
|
|
f762fea |
|
|
|
f762fea |
MAINTAINERCLEANFILES = Makefile.in
|
|
|
f762fea |
diff --git a/tools/mountstats/Makefile.am b/tools/mountstats/Makefile.am
|
|
|
f762fea |
new file mode 100644
|
|
|
f762fea |
index 0000000..ca617a2
|
|
|
f762fea |
--- /dev/null
|
|
|
f762fea |
+++ b/tools/mountstats/Makefile.am
|
|
|
f762fea |
@@ -0,0 +1,13 @@
|
|
|
f762fea |
+## Process this file with automake to produce Makefile.in
|
|
|
f762fea |
+PYTHON_FILES = mountstats.py
|
|
|
f762fea |
+
|
|
|
f762fea |
+man8_MANS = mountstats.man
|
|
|
f762fea |
+
|
|
|
f762fea |
+EXTRA_DIST = $(man8_MANS) $(PYTHON_FILES)
|
|
|
f762fea |
+
|
|
|
f762fea |
+all-local: $(PYTHON_FILES)
|
|
|
f762fea |
+
|
|
|
f762fea |
+install-data-hook:
|
|
|
f762fea |
+ $(INSTALL) --mode 755 mountstats.py $(DESTDIR)$(sbindir)/mountstats
|
|
|
f762fea |
+
|
|
|
f762fea |
+MAINTAINERCLEANFILES=Makefile.in
|
|
|
f762fea |
diff --git a/tools/mountstats/mountstats.man b/tools/mountstats/mountstats.man
|
|
|
f762fea |
new file mode 100644
|
|
|
f762fea |
index 0000000..0de31b7
|
|
|
f762fea |
--- /dev/null
|
|
|
f762fea |
+++ b/tools/mountstats/mountstats.man
|
|
|
f762fea |
@@ -0,0 +1,32 @@
|
|
|
f762fea |
+.\"
|
|
|
f762fea |
+.\" mountstats(8)
|
|
|
f762fea |
+.\"
|
|
|
f762fea |
+.TH mountstats 8 "15 Apr 2010"
|
|
|
f762fea |
+.SH NAME
|
|
|
f762fea |
+mountstats \- Displays NFS client per-mount statistics
|
|
|
f762fea |
+.SH SYNOPSIS
|
|
|
f762fea |
+.BI "mountstats ["<options> "] " <mount_point> " [ " <mount_point> "]"
|
|
|
f762fea |
+.SH DESCRIPTION
|
|
|
f762fea |
+The
|
|
|
f762fea |
+.B mountstats
|
|
|
f762fea |
+command displays NFS client statisitics on each given
|
|
|
f762fea |
+.I <mount_point>
|
|
|
f762fea |
+.SH OPTIONS
|
|
|
f762fea |
+.TP
|
|
|
f762fea |
+.B " \-\-nfs
|
|
|
f762fea |
+display only the NFS statistics
|
|
|
f762fea |
+.TP
|
|
|
f762fea |
+.B " \-\-rpc
|
|
|
f762fea |
+display only the RPC statistics
|
|
|
f762fea |
+.TP
|
|
|
f762fea |
+.B " \-\-version
|
|
|
f762fea |
+display the version of this command
|
|
|
f762fea |
+.SH FILES
|
|
|
f762fea |
+.TP
|
|
|
f762fea |
+.B /proc/self/mountstats
|
|
|
f762fea |
+.SH SEE ALSO
|
|
|
f762fea |
+.BR iostat (8),
|
|
|
f762fea |
+.BR nfsiostat (8),
|
|
|
f762fea |
+.BR nfsstat(8)
|
|
|
f762fea |
+.SH AUTHOR
|
|
|
f762fea |
+Chuck Lever <chuck.lever@oracle.com>
|
|
|
f762fea |
diff --git a/tools/nfs-iostat/Makefile.am b/tools/nfs-iostat/Makefile.am
|
|
|
f762fea |
new file mode 100644
|
|
|
f762fea |
index 0000000..30f4054
|
|
|
f762fea |
--- /dev/null
|
|
|
f762fea |
+++ b/tools/nfs-iostat/Makefile.am
|
|
|
f762fea |
@@ -0,0 +1,13 @@
|
|
|
f762fea |
+## Process this file with automake to produce Makefile.in
|
|
|
f762fea |
+PYTHON_FILES = nfs-iostat.py
|
|
|
f762fea |
+
|
|
|
f762fea |
+man8_MANS = nfsiostat.man
|
|
|
f762fea |
+
|
|
|
f762fea |
+EXTRA_DIST = $(man8_MANS) $(PYTHON_FILES)
|
|
|
f762fea |
+
|
|
|
f762fea |
+all-local: $(PYTHON_FILES)
|
|
|
f762fea |
+
|
|
|
f762fea |
+install-data-hook:
|
|
|
f762fea |
+ $(INSTALL) --mode 755 nfs-iostat.py $(DESTDIR)$(sbindir)/nfsiostat
|
|
|
f762fea |
+
|
|
|
f762fea |
+MAINTAINERCLEANFILES=Makefile.in
|
|
|
f762fea |
diff --git a/tools/nfs-iostat/nfsiostat.man b/tools/nfs-iostat/nfsiostat.man
|
|
|
f762fea |
new file mode 100644
|
|
|
f762fea |
index 0000000..7b1e0a8
|
|
|
f762fea |
--- /dev/null
|
|
|
f762fea |
+++ b/tools/nfs-iostat/nfsiostat.man
|
|
|
f762fea |
@@ -0,0 +1,70 @@
|
|
|
f762fea |
+.\"
|
|
|
f762fea |
+.\" nfsiostat(8)
|
|
|
f762fea |
+.\"
|
|
|
f762fea |
+.TH nfsiostat 8 "15 Apr 2010"
|
|
|
f762fea |
+.SH NAME
|
|
|
f762fea |
+nfsiostat \- Emulate iostat for NFS mount points using /proc/self/mountstats
|
|
|
f762fea |
+.SH SYNOPSIS
|
|
|
f762fea |
+.BI "nfsiostat [[" <interval> "] [" <count> "]] [" <options> "]["<mount_point> "]
|
|
|
f762fea |
+.SH DESCRIPTION
|
|
|
f762fea |
+The
|
|
|
f762fea |
+.B nfsiostat
|
|
|
f762fea |
+command displays NFS client per-mount statisitics.
|
|
|
f762fea |
+.TP
|
|
|
f762fea |
+<interval>
|
|
|
f762fea |
+specifies the amount of time in seconds between each report.
|
|
|
f762fea |
+The first report contains statistics for the time since each file
|
|
|
f762fea |
+system was mounted. Each subsequent report contains statistics collected
|
|
|
f762fea |
+during the interval since the previous report.
|
|
|
f762fea |
+.TP
|
|
|
f762fea |
+<count>
|
|
|
f762fea |
+If the
|
|
|
f762fea |
+.I <count>
|
|
|
f762fea |
+parameter is
|
|
|
f762fea |
+specified, the value of
|
|
|
f762fea |
+.I <count>
|
|
|
f762fea |
+determines the number of reports generated at
|
|
|
f762fea |
+. <interval>
|
|
|
f762fea |
+seconds apart. if the interval parameter is
|
|
|
f762fea |
+specified without the
|
|
|
f762fea |
+.I <count>
|
|
|
f762fea |
+parameter, the command generates reports continuously.
|
|
|
f762fea |
+.TP
|
|
|
f762fea |
+<options>
|
|
|
f762fea |
+Define below
|
|
|
f762fea |
+.TP
|
|
|
f762fea |
+<mount_point>
|
|
|
f762fea |
+If one or more
|
|
|
f762fea |
+.I <mount point>
|
|
|
f762fea |
+names are specified, statistics for only these mount points will
|
|
|
f762fea |
+be displayed. Otherwise, all NFS mount points on the client are listed.
|
|
|
f762fea |
+.SH OPTIONS
|
|
|
f762fea |
+.TP
|
|
|
f762fea |
+.B \-a " or " \-\-attr
|
|
|
f762fea |
+displays statistics related to the attribute cache
|
|
|
f762fea |
+.TP
|
|
|
f762fea |
+.B \-d " or " \-\-dir
|
|
|
f762fea |
+displays statistics related to directory operations
|
|
|
f762fea |
+.TP
|
|
|
f762fea |
+.B \-h " or " \-\-help
|
|
|
f762fea |
+shows help message and exit
|
|
|
f762fea |
+.TP
|
|
|
f762fea |
+.B \-l LIST or " \-\-list=LIST
|
|
|
f762fea |
+only print stats for first LIST mount points
|
|
|
f762fea |
+.TP
|
|
|
f762fea |
+.B \-p " or " \-\-page
|
|
|
f762fea |
+displays statistics related to the page cache
|
|
|
f762fea |
+.TP
|
|
|
f762fea |
+.B \-s " or " \-\-sort
|
|
|
f762fea |
+Sort NFS mount points by ops/second
|
|
|
f762fea |
+.B \-\-version
|
|
|
f762fea |
+show program's version number and exit
|
|
|
f762fea |
+.SH FILES
|
|
|
f762fea |
+.TP
|
|
|
f762fea |
+.B /proc/self/mountstats
|
|
|
f762fea |
+.SH SEE ALSO
|
|
|
f762fea |
+.BR iostat (8),
|
|
|
f762fea |
+.BR mountstats (8),
|
|
|
f762fea |
+.BR nfsstat(8)
|
|
|
f762fea |
+.SH AUTHOR
|
|
|
f762fea |
+Chuck Lever <chuck.lever@oracle.com>
|
|
|
f762fea |
diff --git a/utils/gssd/context.h b/utils/gssd/context.h
|
|
|
f762fea |
index be47f9c..c9cb0bd 100644
|
|
|
f762fea |
--- a/utils/gssd/context.h
|
|
|
f762fea |
+++ b/utils/gssd/context.h
|
|
|
f762fea |
@@ -1,5 +1,5 @@
|
|
|
f762fea |
/*
|
|
|
f762fea |
- Copyright (c) 2004 The Regents of the University of Michigan.
|
|
|
f762fea |
+ Copyright (c) 2004,2008 The Regents of the University of Michigan.
|
|
|
f762fea |
All rights reserved.
|
|
|
f762fea |
|
|
|
f762fea |
Redistribution and use in source and binary forms, with or without
|
|
|
f762fea |
@@ -36,6 +36,10 @@
|
|
|
f762fea |
/* Hopefully big enough to hold any serialized context */
|
|
|
f762fea |
#define MAX_CTX_LEN 4096
|
|
|
f762fea |
|
|
|
f762fea |
+/* New context format flag values */
|
|
|
f762fea |
+#define KRB5_CTX_FLAG_INITIATOR 0x00000001
|
|
|
f762fea |
+#define KRB5_CTX_FLAG_CFX 0x00000002
|
|
|
f762fea |
+#define KRB5_CTX_FLAG_ACCEPTOR_SUBKEY 0x00000004
|
|
|
f762fea |
|
|
|
f762fea |
int serialize_context_for_kernel(gss_ctx_id_t ctx, gss_buffer_desc *buf,
|
|
|
f762fea |
gss_OID mech, int32_t *endtime);
|
|
|
f762fea |
diff --git a/utils/gssd/context_lucid.c b/utils/gssd/context_lucid.c
|
|
|
f762fea |
index 4a682ae..b87bf76 100644
|
|
|
f762fea |
--- a/utils/gssd/context_lucid.c
|
|
|
f762fea |
+++ b/utils/gssd/context_lucid.c
|
|
|
f762fea |
@@ -42,6 +42,7 @@
|
|
|
f762fea |
#include <stdio.h>
|
|
|
f762fea |
#include <syslog.h>
|
|
|
f762fea |
#include <string.h>
|
|
|
f762fea |
+#include <errno.h>
|
|
|
f762fea |
|
|
|
f762fea |
#include <gssapi/gssapi_krb5.h>
|
|
|
f762fea |
|
|
|
f762fea |
@@ -119,15 +120,13 @@ prepare_krb5_rfc1964_buffer(gss_krb5_lucid_context_v1_t *lctx,
|
|
|
f762fea |
* Note that the rfc1964 version only supports DES enctypes.
|
|
|
f762fea |
*/
|
|
|
f762fea |
if (lctx->rfc1964_kd.ctx_key.type != 4) {
|
|
|
f762fea |
- printerr(1, "prepare_krb5_rfc1964_buffer: "
|
|
|
f762fea |
- "overriding heimdal keytype (%d => %d)\n",
|
|
|
f762fea |
- lctx->rfc1964_kd.ctx_key.type, 4);
|
|
|
f762fea |
+ printerr(2, "%s: overriding heimdal keytype (%d => %d)\n",
|
|
|
f762fea |
+ __FUNCTION__, lctx->rfc1964_kd.ctx_key.type, 4);
|
|
|
f762fea |
lctx->rfc1964_kd.ctx_key.type = 4;
|
|
|
f762fea |
}
|
|
|
f762fea |
#endif
|
|
|
f762fea |
- printerr(2, "prepare_krb5_rfc1964_buffer: serializing keys with "
|
|
|
f762fea |
- "enctype %d and length %d\n",
|
|
|
f762fea |
- lctx->rfc1964_kd.ctx_key.type,
|
|
|
f762fea |
+ printerr(2, "%s: serializing keys with enctype %d and length %d\n",
|
|
|
f762fea |
+ __FUNCTION__, lctx->rfc1964_kd.ctx_key.type,
|
|
|
f762fea |
lctx->rfc1964_kd.ctx_key.length);
|
|
|
f762fea |
|
|
|
f762fea |
/* derive the encryption key and copy it into buffer */
|
|
|
f762fea |
@@ -158,11 +157,100 @@ out_err:
|
|
|
f762fea |
return -1;
|
|
|
f762fea |
}
|
|
|
f762fea |
|
|
|
f762fea |
+/* Flags for version 2 context flags */
|
|
|
f762fea |
+#define KRB5_CTX_FLAG_INITIATOR 0x00000001
|
|
|
f762fea |
+#define KRB5_CTX_FLAG_CFX 0x00000002
|
|
|
f762fea |
+#define KRB5_CTX_FLAG_ACCEPTOR_SUBKEY 0x00000004
|
|
|
f762fea |
+
|
|
|
f762fea |
+/*
|
|
|
f762fea |
+ * Prepare a new-style buffer, as defined in rfc4121 (a.k.a. cfx),
|
|
|
f762fea |
+ * to send to the kernel for newer encryption types -- or for DES3.
|
|
|
f762fea |
+ *
|
|
|
f762fea |
+ * The new format is:
|
|
|
f762fea |
+ *
|
|
|
f762fea |
+ * u32 flags;
|
|
|
f762fea |
+ * #define KRB5_CTX_FLAG_INITIATOR 0x00000001
|
|
|
f762fea |
+ * #define KRB5_CTX_FLAG_CFX 0x00000002
|
|
|
f762fea |
+ * #define KRB5_CTX_FLAG_ACCEPTOR_SUBKEY 0x00000004
|
|
|
f762fea |
+ * s32 endtime;
|
|
|
f762fea |
+ * u64 seq_send;
|
|
|
f762fea |
+ * u32 enctype; ( encrption type of key )
|
|
|
f762fea |
+ * raw key; ( raw key bytes (kernel will derive))
|
|
|
f762fea |
+ *
|
|
|
f762fea |
+ */
|
|
|
f762fea |
static int
|
|
|
f762fea |
-prepare_krb5_rfc_cfx_buffer(gss_krb5_lucid_context_v1_t *lctx,
|
|
|
f762fea |
+prepare_krb5_rfc4121_buffer(gss_krb5_lucid_context_v1_t *lctx,
|
|
|
f762fea |
gss_buffer_desc *buf, int32_t *endtime)
|
|
|
f762fea |
{
|
|
|
f762fea |
- printerr(0, "ERROR: prepare_krb5_rfc_cfx_buffer: not implemented\n");
|
|
|
f762fea |
+ char *p, *end;
|
|
|
f762fea |
+ uint32_t v2_flags = 0;
|
|
|
f762fea |
+ uint32_t enctype;
|
|
|
f762fea |
+ uint32_t keysize;
|
|
|
f762fea |
+
|
|
|
f762fea |
+ if (!(buf->value = calloc(1, MAX_CTX_LEN)))
|
|
|
f762fea |
+ goto out_err;
|
|
|
f762fea |
+ p = buf->value;
|
|
|
f762fea |
+ end = buf->value + MAX_CTX_LEN;
|
|
|
f762fea |
+
|
|
|
f762fea |
+ /* Version 2 */
|
|
|
f762fea |
+ if (lctx->initiate)
|
|
|
f762fea |
+ v2_flags |= KRB5_CTX_FLAG_INITIATOR;
|
|
|
f762fea |
+ if (lctx->protocol != 0)
|
|
|
f762fea |
+ v2_flags |= KRB5_CTX_FLAG_CFX;
|
|
|
f762fea |
+ if (lctx->protocol != 0 && lctx->cfx_kd.have_acceptor_subkey == 1)
|
|
|
f762fea |
+ v2_flags |= KRB5_CTX_FLAG_ACCEPTOR_SUBKEY;
|
|
|
f762fea |
+
|
|
|
f762fea |
+ if (WRITE_BYTES(&p, end, v2_flags)) goto out_err;
|
|
|
f762fea |
+ if (WRITE_BYTES(&p, end, lctx->endtime)) goto out_err;
|
|
|
f762fea |
+ if (WRITE_BYTES(&p, end, lctx->send_seq)) goto out_err;
|
|
|
f762fea |
+
|
|
|
f762fea |
+ /* Protocol 0 here implies DES3 or RC4 */
|
|
|
f762fea |
+ printerr(2, "%s: protocol %d\n", __FUNCTION__, lctx->protocol);
|
|
|
f762fea |
+ if (lctx->protocol == 0) {
|
|
|
f762fea |
+ enctype = lctx->rfc1964_kd.ctx_key.type;
|
|
|
f762fea |
+ keysize = lctx->rfc1964_kd.ctx_key.length;
|
|
|
f762fea |
+ } else {
|
|
|
f762fea |
+ if (lctx->cfx_kd.have_acceptor_subkey) {
|
|
|
f762fea |
+ enctype = lctx->cfx_kd.acceptor_subkey.type;
|
|
|
f762fea |
+ keysize = lctx->cfx_kd.acceptor_subkey.length;
|
|
|
f762fea |
+ } else {
|
|
|
f762fea |
+ enctype = lctx->cfx_kd.ctx_key.type;
|
|
|
f762fea |
+ keysize = lctx->cfx_kd.ctx_key.length;
|
|
|
f762fea |
+ }
|
|
|
f762fea |
+ }
|
|
|
f762fea |
+ printerr(2, "%s: serializing key with enctype %d and size %d\n",
|
|
|
f762fea |
+ __FUNCTION__, enctype, keysize);
|
|
|
f762fea |
+
|
|
|
f762fea |
+ if (WRITE_BYTES(&p, end, enctype)) goto out_err;
|
|
|
f762fea |
+
|
|
|
f762fea |
+ if (lctx->protocol == 0) {
|
|
|
f762fea |
+ if (write_bytes(&p, end, lctx->rfc1964_kd.ctx_key.data,
|
|
|
f762fea |
+ lctx->rfc1964_kd.ctx_key.length))
|
|
|
f762fea |
+ goto out_err;
|
|
|
f762fea |
+ } else {
|
|
|
f762fea |
+ if (lctx->cfx_kd.have_acceptor_subkey) {
|
|
|
f762fea |
+ if (write_bytes(&p, end,
|
|
|
f762fea |
+ lctx->cfx_kd.acceptor_subkey.data,
|
|
|
f762fea |
+ lctx->cfx_kd.acceptor_subkey.length))
|
|
|
f762fea |
+ goto out_err;
|
|
|
f762fea |
+ } else {
|
|
|
f762fea |
+ if (write_bytes(&p, end, lctx->cfx_kd.ctx_key.data,
|
|
|
f762fea |
+ lctx->cfx_kd.ctx_key.length))
|
|
|
f762fea |
+ goto out_err;
|
|
|
f762fea |
+ }
|
|
|
f762fea |
+ }
|
|
|
f762fea |
+
|
|
|
f762fea |
+ buf->length = p - (char *)buf->value;
|
|
|
f762fea |
+ return 0;
|
|
|
f762fea |
+
|
|
|
f762fea |
+out_err:
|
|
|
f762fea |
+ printerr(0, "ERROR: %s: failed serializing krb5 context for kernel\n",
|
|
|
f762fea |
+ __FUNCTION__);
|
|
|
f762fea |
+ if (buf->value) {
|
|
|
f762fea |
+ free(buf->value);
|
|
|
f762fea |
+ buf->value = NULL;
|
|
|
f762fea |
+ }
|
|
|
f762fea |
+ buf->length = 0;
|
|
|
f762fea |
return -1;
|
|
|
f762fea |
}
|
|
|
f762fea |
|
|
|
f762fea |
@@ -176,7 +264,7 @@ serialize_krb5_ctx(gss_ctx_id_t ctx, gss_buffer_desc *buf, int32_t *endtime)
|
|
|
f762fea |
gss_krb5_lucid_context_v1_t *lctx = 0;
|
|
|
f762fea |
int retcode = 0;
|
|
|
f762fea |
|
|
|
f762fea |
- printerr(2, "DEBUG: serialize_krb5_ctx: lucid version!\n");
|
|
|
f762fea |
+ printerr(2, "DEBUG: %s: lucid version!\n", __FUNCTION__);
|
|
|
f762fea |
maj_stat = gss_export_lucid_sec_context(&min_stat, &ctx,
|
|
|
f762fea |
1, &return_ctx);
|
|
|
f762fea |
if (maj_stat != GSS_S_COMPLETE) {
|
|
|
f762fea |
@@ -198,11 +286,20 @@ serialize_krb5_ctx(gss_ctx_id_t ctx, gss_buffer_desc *buf, int32_t *endtime)
|
|
|
f762fea |
break;
|
|
|
f762fea |
}
|
|
|
f762fea |
|
|
|
f762fea |
- /* Now lctx points to a lucid context that we can send down to kernel */
|
|
|
f762fea |
- if (lctx->protocol == 0)
|
|
|
f762fea |
+ /*
|
|
|
f762fea |
+ * Now lctx points to a lucid context that we can send down to kernel
|
|
|
f762fea |
+ *
|
|
|
f762fea |
+ * Note: we send down different information to the kernel depending
|
|
|
f762fea |
+ * on the protocol version and the enctyption type.
|
|
|
f762fea |
+ * For protocol version 0 with all enctypes besides DES3, we use
|
|
|
f762fea |
+ * the original format. For protocol version != 0 or DES3, we
|
|
|
f762fea |
+ * send down the new style information.
|
|
|
f762fea |
+ */
|
|
|
f762fea |
+
|
|
|
f762fea |
+ if (lctx->protocol == 0 && lctx->rfc1964_kd.ctx_key.type <= 4)
|
|
|
f762fea |
retcode = prepare_krb5_rfc1964_buffer(lctx, buf, endtime);
|
|
|
f762fea |
else
|
|
|
f762fea |
- retcode = prepare_krb5_rfc_cfx_buffer(lctx, buf, endtime);
|
|
|
f762fea |
+ retcode = prepare_krb5_rfc4121_buffer(lctx, buf, endtime);
|
|
|
f762fea |
|
|
|
f762fea |
maj_stat = gss_free_lucid_sec_context(&min_stat, ctx, return_ctx);
|
|
|
f762fea |
if (maj_stat != GSS_S_COMPLETE) {
|
|
|
f762fea |
@@ -212,8 +309,8 @@ serialize_krb5_ctx(gss_ctx_id_t ctx, gss_buffer_desc *buf, int32_t *endtime)
|
|
|
f762fea |
}
|
|
|
f762fea |
|
|
|
f762fea |
if (retcode) {
|
|
|
f762fea |
- printerr(1, "serialize_krb5_ctx: prepare_krb5_*_buffer "
|
|
|
f762fea |
- "failed (retcode = %d)\n", retcode);
|
|
|
f762fea |
+ printerr(1, "%s: prepare_krb5_*_buffer failed (retcode = %d)\n",
|
|
|
f762fea |
+ __FUNCTION__, retcode);
|
|
|
f762fea |
goto out_err;
|
|
|
f762fea |
}
|
|
|
f762fea |
|
|
|
f762fea |
@@ -223,4 +320,7 @@ out_err:
|
|
|
f762fea |
printerr(0, "ERROR: failed serializing krb5 context for kernel\n");
|
|
|
f762fea |
return -1;
|
|
|
f762fea |
}
|
|
|
f762fea |
+
|
|
|
f762fea |
+
|
|
|
f762fea |
+
|
|
|
f762fea |
#endif /* HAVE_LUCID_CONTEXT_SUPPORT */
|
|
|
f762fea |
diff --git a/utils/gssd/context_mit.c b/utils/gssd/context_mit.c
|
|
|
f762fea |
index 709a903..f9cbb02 100644
|
|
|
f762fea |
--- a/utils/gssd/context_mit.c
|
|
|
f762fea |
+++ b/utils/gssd/context_mit.c
|
|
|
f762fea |
@@ -1,5 +1,5 @@
|
|
|
f762fea |
/*
|
|
|
f762fea |
- Copyright (c) 2004 The Regents of the University of Michigan.
|
|
|
f762fea |
+ Copyright (c) 2004-2006 The Regents of the University of Michigan.
|
|
|
f762fea |
All rights reserved.
|
|
|
f762fea |
|
|
|
f762fea |
Redistribution and use in source and binary forms, with or without
|
|
|
f762fea |
@@ -38,6 +38,7 @@
|
|
|
f762fea |
#include <stdio.h>
|
|
|
f762fea |
#include <syslog.h>
|
|
|
f762fea |
#include <string.h>
|
|
|
f762fea |
+#include <errno.h>
|
|
|
f762fea |
#include <gssapi/gssapi.h>
|
|
|
f762fea |
#include <rpc/rpc.h>
|
|
|
f762fea |
#include <rpc/auth_gss.h>
|
|
|
f762fea |
@@ -52,8 +53,7 @@
|
|
|
f762fea |
/* XXX argggg, there's gotta be a better way than just duplicating this
|
|
|
f762fea |
* whole struct. Unfortunately, this is in a "private" header file,
|
|
|
f762fea |
* so this is our best choice at this point :-/
|
|
|
f762fea |
- *
|
|
|
f762fea |
- * XXX Does this match the Heimdal definition? */
|
|
|
f762fea |
+ */
|
|
|
f762fea |
|
|
|
f762fea |
typedef struct _krb5_gss_ctx_id_rec {
|
|
|
f762fea |
unsigned int initiate : 1; /* nonzero if initiating, zero if accepting */
|
|
|
f762fea |
@@ -156,50 +156,120 @@ serialize_krb5_ctx(gss_ctx_id_t ctx, gss_buffer_desc *buf, int32_t *endtime)
|
|
|
f762fea |
{
|
|
|
f762fea |
krb5_gss_ctx_id_t kctx = ((gss_union_ctx_id_t)ctx)->internal_ctx_id;
|
|
|
f762fea |
char *p, *end;
|
|
|
f762fea |
- static int constant_one = 1;
|
|
|
f762fea |
static int constant_zero = 0;
|
|
|
f762fea |
+ static int constant_one = 1;
|
|
|
f762fea |
+ static int constant_two = 2;
|
|
|
f762fea |
uint32_t word_seq_send;
|
|
|
f762fea |
+ u_int64_t seq_send_64bit;
|
|
|
f762fea |
+ uint32_t v2_flags = 0;
|
|
|
f762fea |
|
|
|
f762fea |
if (!(buf->value = calloc(1, MAX_CTX_LEN)))
|
|
|
f762fea |
goto out_err;
|
|
|
f762fea |
p = buf->value;
|
|
|
f762fea |
end = buf->value + MAX_CTX_LEN;
|
|
|
f762fea |
|
|
|
f762fea |
- if (kctx->initiate) {
|
|
|
f762fea |
- if (WRITE_BYTES(&p, end, constant_one)) goto out_err;
|
|
|
f762fea |
- }
|
|
|
f762fea |
- else {
|
|
|
f762fea |
- if (WRITE_BYTES(&p, end, constant_zero)) goto out_err;
|
|
|
f762fea |
- }
|
|
|
f762fea |
- if (kctx->seed_init) {
|
|
|
f762fea |
- if (WRITE_BYTES(&p, end, constant_one)) goto out_err;
|
|
|
f762fea |
- }
|
|
|
f762fea |
- else {
|
|
|
f762fea |
- if (WRITE_BYTES(&p, end, constant_zero)) goto out_err;
|
|
|
f762fea |
- }
|
|
|
f762fea |
- if (write_bytes(&p, end, &kctx->seed, sizeof(kctx->seed)))
|
|
|
f762fea |
+ switch (kctx->enc->enctype) {
|
|
|
f762fea |
+ case ENCTYPE_DES_CBC_CRC:
|
|
|
f762fea |
+ case ENCTYPE_DES_CBC_MD4:
|
|
|
f762fea |
+ case ENCTYPE_DES_CBC_MD5:
|
|
|
f762fea |
+ case ENCTYPE_DES_CBC_RAW:
|
|
|
f762fea |
+ /* Old format of context to the kernel */
|
|
|
f762fea |
+ if (kctx->initiate) {
|
|
|
f762fea |
+ if (WRITE_BYTES(&p, end, constant_one)) goto out_err;
|
|
|
f762fea |
+ }
|
|
|
f762fea |
+ else {
|
|
|
f762fea |
+ if (WRITE_BYTES(&p, end, constant_zero)) goto out_err;
|
|
|
f762fea |
+ }
|
|
|
f762fea |
+ if (kctx->seed_init) {
|
|
|
f762fea |
+ if (WRITE_BYTES(&p, end, constant_one)) goto out_err;
|
|
|
f762fea |
+ }
|
|
|
f762fea |
+ else {
|
|
|
f762fea |
+ if (WRITE_BYTES(&p, end, constant_zero)) goto out_err;
|
|
|
f762fea |
+ }
|
|
|
f762fea |
+ if (write_bytes(&p, end, &kctx->seed, sizeof(kctx->seed)))
|
|
|
f762fea |
+ goto out_err;
|
|
|
f762fea |
+ if (WRITE_BYTES(&p, end, kctx->signalg)) goto out_err;
|
|
|
f762fea |
+ if (WRITE_BYTES(&p, end, kctx->sealalg)) goto out_err;
|
|
|
f762fea |
+ if (WRITE_BYTES(&p, end, kctx->endtime)) goto out_err;
|
|
|
f762fea |
+ word_seq_send = kctx->seq_send;
|
|
|
f762fea |
+ if (WRITE_BYTES(&p, end, word_seq_send)) goto out_err;
|
|
|
f762fea |
+ if (write_oid(&p, end, kctx->mech_used)) goto out_err;
|
|
|
f762fea |
+
|
|
|
f762fea |
+ printerr(2, "serialize_krb5_ctx: serializing keys with "
|
|
|
f762fea |
+ "enctype %d and length %d\n",
|
|
|
f762fea |
+ kctx->enc->enctype, kctx->enc->length);
|
|
|
f762fea |
+
|
|
|
f762fea |
+ if (write_keyblock(&p, end, kctx->enc)) goto out_err;
|
|
|
f762fea |
+ if (write_keyblock(&p, end, kctx->seq)) goto out_err;
|
|
|
f762fea |
+ break;
|
|
|
f762fea |
+ case ENCTYPE_DES3_CBC_RAW:
|
|
|
f762fea |
+ case ENCTYPE_DES3_CBC_SHA1:
|
|
|
f762fea |
+ case ENCTYPE_ARCFOUR_HMAC:
|
|
|
f762fea |
+ case ENCTYPE_ARCFOUR_HMAC_EXP:
|
|
|
f762fea |
+ case ENCTYPE_AES128_CTS_HMAC_SHA1_96:
|
|
|
f762fea |
+ case ENCTYPE_AES256_CTS_HMAC_SHA1_96:
|
|
|
f762fea |
+ /* New format of context to the kernel */
|
|
|
f762fea |
+ /* u32 flags;
|
|
|
f762fea |
+ * #define KRB5_CTX_FLAG_INITIATOR 0x00000001
|
|
|
f762fea |
+ * #define KRB5_CTX_FLAG_CFX 0x00000002
|
|
|
f762fea |
+ * #define KRB5_CTX_FLAG_ACCEPTOR_SUBKEY 0x00000004
|
|
|
f762fea |
+ * s32 endtime;
|
|
|
f762fea |
+ * u64 seq_send;
|
|
|
f762fea |
+ * u32 enctype;
|
|
|
f762fea |
+ * rawkey data
|
|
|
f762fea |
+ */
|
|
|
f762fea |
+
|
|
|
f762fea |
+ if (kctx->initiate)
|
|
|
f762fea |
+ v2_flags |= KRB5_CTX_FLAG_INITIATOR;
|
|
|
f762fea |
+ if (kctx->proto == 1)
|
|
|
f762fea |
+ v2_flags |= KRB5_CTX_FLAG_CFX;
|
|
|
f762fea |
+ if (kctx->have_acceptor_subkey)
|
|
|
f762fea |
+ v2_flags |= KRB5_CTX_FLAG_ACCEPTOR_SUBKEY;
|
|
|
f762fea |
+ if (WRITE_BYTES(&p, end, v2_flags)) goto out_err;
|
|
|
f762fea |
+ if (WRITE_BYTES(&p, end, kctx->endtime)) goto out_err;
|
|
|
f762fea |
+
|
|
|
f762fea |
+ seq_send_64bit = kctx->seq_send;
|
|
|
f762fea |
+ if (WRITE_BYTES(&p, end, seq_send_64bit)) goto out_err;
|
|
|
f762fea |
+
|
|
|
f762fea |
+ if (kctx->have_acceptor_subkey) {
|
|
|
f762fea |
+ if (WRITE_BYTES(&p, end, kctx->acceptor_subkey->enctype))
|
|
|
f762fea |
+ goto out_err;
|
|
|
f762fea |
+ printerr(2, "serialize_krb5_ctx: serializing subkey "
|
|
|
f762fea |
+ "with enctype %d and size %d\n",
|
|
|
f762fea |
+ kctx->acceptor_subkey->enctype,
|
|
|
f762fea |
+ kctx->acceptor_subkey->length);
|
|
|
f762fea |
+
|
|
|
f762fea |
+ if (write_bytes(&p, end,
|
|
|
f762fea |
+ kctx->acceptor_subkey->contents,
|
|
|
f762fea |
+ kctx->acceptor_subkey->length))
|
|
|
f762fea |
+ goto out_err;
|
|
|
f762fea |
+ } else {
|
|
|
f762fea |
+ if (WRITE_BYTES(&p, end, kctx->enc->enctype))
|
|
|
f762fea |
+ goto out_err;
|
|
|
f762fea |
+ printerr(2, "serialize_krb5_ctx: serializing key "
|
|
|
f762fea |
+ "with enctype %d and size %d\n",
|
|
|
f762fea |
+ kctx->enc->enctype, kctx->enc->length);
|
|
|
f762fea |
+
|
|
|
f762fea |
+ if (write_bytes(&p, end, kctx->enc->contents,
|
|
|
f762fea |
+ kctx->enc->length))
|
|
|
f762fea |
+ goto out_err;
|
|
|
f762fea |
+ }
|
|
|
f762fea |
+ break;
|
|
|
f762fea |
+ default:
|
|
|
f762fea |
+ printerr(0, "ERROR: serialize_krb5_ctx: unsupported encryption "
|
|
|
f762fea |
+ "algorithm %d\n", kctx->enc->enctype);
|
|
|
f762fea |
goto out_err;
|
|
|
f762fea |
- if (WRITE_BYTES(&p, end, kctx->signalg)) goto out_err;
|
|
|
f762fea |
- if (WRITE_BYTES(&p, end, kctx->sealalg)) goto out_err;
|
|
|
f762fea |
- if (WRITE_BYTES(&p, end, kctx->endtime)) goto out_err;
|
|
|
f762fea |
- if (endtime)
|
|
|
f762fea |
- *endtime = kctx->endtime;
|
|
|
f762fea |
- word_seq_send = kctx->seq_send;
|
|
|
f762fea |
- if (WRITE_BYTES(&p, end, word_seq_send)) goto out_err;
|
|
|
f762fea |
- if (write_oid(&p, end, kctx->mech_used)) goto out_err;
|
|
|
f762fea |
-
|
|
|
f762fea |
- printerr(2, "serialize_krb5_ctx: serializing keys with "
|
|
|
f762fea |
- "enctype %d and length %d\n",
|
|
|
f762fea |
- kctx->enc->enctype, kctx->enc->length);
|
|
|
f762fea |
-
|
|
|
f762fea |
- if (write_keyblock(&p, end, kctx->enc)) goto out_err;
|
|
|
f762fea |
- if (write_keyblock(&p, end, kctx->seq)) goto out_err;
|
|
|
f762fea |
+ }
|
|
|
f762fea |
|
|
|
f762fea |
buf->length = p - (char *)buf->value;
|
|
|
f762fea |
return 0;
|
|
|
f762fea |
+
|
|
|
f762fea |
out_err:
|
|
|
f762fea |
printerr(0, "ERROR: failed serializing krb5 context for kernel\n");
|
|
|
f762fea |
- if (buf->value) free(buf->value);
|
|
|
f762fea |
+ if (buf->value) {
|
|
|
f762fea |
+ free(buf->value);
|
|
|
f762fea |
+ }
|
|
|
f762fea |
+ buf->value = NULL;
|
|
|
f762fea |
buf->length = 0;
|
|
|
f762fea |
return -1;
|
|
|
f762fea |
}
|
|
|
f762fea |
diff --git a/utils/gssd/gssd_proc.c b/utils/gssd/gssd_proc.c
|
|
|
f762fea |
index be4fb11..a55418b 100644
|
|
|
f762fea |
--- a/utils/gssd/gssd_proc.c
|
|
|
f762fea |
+++ b/utils/gssd/gssd_proc.c
|
|
|
f762fea |
@@ -600,6 +600,67 @@ update_client_list(void)
|
|
|
f762fea |
return retval;
|
|
|
f762fea |
}
|
|
|
f762fea |
|
|
|
f762fea |
+/* Encryption types supported by the kernel rpcsec_gss code */
|
|
|
f762fea |
+int num_krb5_enctypes = 0;
|
|
|
f762fea |
+krb5_enctype *krb5_enctypes = NULL;
|
|
|
f762fea |
+
|
|
|
f762fea |
+/*
|
|
|
f762fea |
+ * Parse the supported encryption type information
|
|
|
f762fea |
+ */
|
|
|
f762fea |
+static int
|
|
|
f762fea |
+parse_enctypes(char *enctypes)
|
|
|
f762fea |
+{
|
|
|
f762fea |
+ int n = 0;
|
|
|
f762fea |
+ char *curr, *comma;
|
|
|
f762fea |
+ int i;
|
|
|
f762fea |
+ static char *cached_types;
|
|
|
f762fea |
+
|
|
|
f762fea |
+ if (cached_types && strcmp(cached_types, enctypes) == 0)
|
|
|
f762fea |
+ return 0;
|
|
|
f762fea |
+ free(cached_types);
|
|
|
f762fea |
+
|
|
|
f762fea |
+ if (krb5_enctypes != NULL) {
|
|
|
f762fea |
+ free(krb5_enctypes);
|
|
|
f762fea |
+ krb5_enctypes = NULL;
|
|
|
f762fea |
+ num_krb5_enctypes = 0;
|
|
|
f762fea |
+ }
|
|
|
f762fea |
+
|
|
|
f762fea |
+ /* count the number of commas */
|
|
|
f762fea |
+ for (curr = enctypes; curr && *curr != '\0'; curr = ++comma) {
|
|
|
f762fea |
+ comma = strchr(curr, ',');
|
|
|
f762fea |
+ if (comma != NULL)
|
|
|
f762fea |
+ n++;
|
|
|
f762fea |
+ else
|
|
|
f762fea |
+ break;
|
|
|
f762fea |
+ }
|
|
|
f762fea |
+ /* If no more commas and we're not at the end, there's one more value */
|
|
|
f762fea |
+ if (*curr != '\0')
|
|
|
f762fea |
+ n++;
|
|
|
f762fea |
+
|
|
|
f762fea |
+ /* Empty string, return an error */
|
|
|
f762fea |
+ if (n == 0)
|
|
|
f762fea |
+ return ENOENT;
|
|
|
f762fea |
+
|
|
|
f762fea |
+ /* Allocate space for enctypes array */
|
|
|
f762fea |
+ if ((krb5_enctypes = (int *) calloc(n, sizeof(int))) == NULL) {
|
|
|
f762fea |
+ return ENOMEM;
|
|
|
f762fea |
+ }
|
|
|
f762fea |
+
|
|
|
f762fea |
+ /* Now parse each value into the array */
|
|
|
f762fea |
+ for (curr = enctypes, i = 0; curr && *curr != '\0'; curr = ++comma) {
|
|
|
f762fea |
+ krb5_enctypes[i++] = atoi(curr);
|
|
|
f762fea |
+ comma = strchr(curr, ',');
|
|
|
f762fea |
+ if (comma == NULL)
|
|
|
f762fea |
+ break;
|
|
|
f762fea |
+ }
|
|
|
f762fea |
+
|
|
|
f762fea |
+ num_krb5_enctypes = n;
|
|
|
f762fea |
+ if ((cached_types = malloc(strlen(enctypes)+1)))
|
|
|
f762fea |
+ strcpy(cached_types, enctypes);
|
|
|
f762fea |
+
|
|
|
f762fea |
+ return 0;
|
|
|
f762fea |
+}
|
|
|
f762fea |
+
|
|
|
f762fea |
static int
|
|
|
f762fea |
do_downcall(int k5_fd, uid_t uid, struct authgss_private_data *pd,
|
|
|
f762fea |
gss_buffer_desc *context_token)
|
|
|
f762fea |
@@ -1133,6 +1194,7 @@ handle_gssd_upcall(struct clnt_info *clp)
|
|
|
f762fea |
char *mech = NULL;
|
|
|
f762fea |
char *target = NULL;
|
|
|
f762fea |
char *service = NULL;
|
|
|
f762fea |
+ char *enctypes = NULL;
|
|
|
f762fea |
|
|
|
f762fea |
printerr(1, "handling gssd upcall (%s)\n", clp->dirname);
|
|
|
f762fea |
|
|
|
f762fea |
@@ -1176,6 +1238,23 @@ handle_gssd_upcall(struct clnt_info *clp)
|
|
|
f762fea |
goto out;
|
|
|
f762fea |
}
|
|
|
f762fea |
|
|
|
f762fea |
+ /* read supported encryption types if supplied */
|
|
|
f762fea |
+ if ((p = strstr(lbuf, "enctypes=")) != NULL) {
|
|
|
f762fea |
+ enctypes = malloc(lbuflen);
|
|
|
f762fea |
+ if (!enctypes)
|
|
|
f762fea |
+ goto out;
|
|
|
f762fea |
+ if (sscanf(p, "enctypes=%s", enctypes) != 1) {
|
|
|
f762fea |
+ printerr(0, "WARNING: handle_gssd_upcall: "
|
|
|
f762fea |
+ "failed to parse target name "
|
|
|
f762fea |
+ "in upcall string '%s'\n", lbuf);
|
|
|
f762fea |
+ goto out;
|
|
|
f762fea |
+ }
|
|
|
f762fea |
+ if (parse_enctypes(enctypes) != 0) {
|
|
|
f762fea |
+ printerr(0, "WARNING: handle_gssd_upcall: "
|
|
|
f762fea |
+ "parsing encryption types failed: errno %d\n", errno);
|
|
|
f762fea |
+ }
|
|
|
f762fea |
+ }
|
|
|
f762fea |
+
|
|
|
f762fea |
/* read target name */
|
|
|
f762fea |
if ((p = strstr(lbuf, "target=")) != NULL) {
|
|
|
f762fea |
target = malloc(lbuflen);
|
|
|
f762fea |
@@ -1222,6 +1301,7 @@ handle_gssd_upcall(struct clnt_info *clp)
|
|
|
f762fea |
out:
|
|
|
f762fea |
free(lbuf);
|
|
|
f762fea |
free(mech);
|
|
|
f762fea |
+ free(enctypes);
|
|
|
f762fea |
free(target);
|
|
|
f762fea |
free(service);
|
|
|
f762fea |
return;
|
|
|
f762fea |
diff --git a/utils/gssd/krb5_util.c b/utils/gssd/krb5_util.c
|
|
|
f762fea |
index 1295f57..dccbeb6 100644
|
|
|
f762fea |
--- a/utils/gssd/krb5_util.c
|
|
|
f762fea |
+++ b/utils/gssd/krb5_util.c
|
|
|
f762fea |
@@ -292,61 +292,6 @@ gssd_find_existing_krb5_ccache(uid_t uid, char *dirname, struct dirent **d)
|
|
|
f762fea |
return err;
|
|
|
f762fea |
}
|
|
|
f762fea |
|
|
|
f762fea |
-
|
|
|
f762fea |
-#ifdef HAVE_SET_ALLOWABLE_ENCTYPES
|
|
|
f762fea |
-/*
|
|
|
f762fea |
- * this routine obtains a credentials handle via gss_acquire_cred()
|
|
|
f762fea |
- * then calls gss_krb5_set_allowable_enctypes() to limit the encryption
|
|
|
f762fea |
- * types negotiated.
|
|
|
f762fea |
- *
|
|
|
f762fea |
- * XXX Should call some function to determine the enctypes supported
|
|
|
f762fea |
- * by the kernel. (Only need to do that once!)
|
|
|
f762fea |
- *
|
|
|
f762fea |
- * Returns:
|
|
|
f762fea |
- * 0 => all went well
|
|
|
f762fea |
- * -1 => there was an error
|
|
|
f762fea |
- */
|
|
|
f762fea |
-
|
|
|
f762fea |
-int
|
|
|
f762fea |
-limit_krb5_enctypes(struct rpc_gss_sec *sec, uid_t uid)
|
|
|
f762fea |
-{
|
|
|
f762fea |
- u_int maj_stat, min_stat;
|
|
|
f762fea |
- gss_cred_id_t credh;
|
|
|
f762fea |
- gss_OID_set_desc desired_mechs;
|
|
|
f762fea |
- krb5_enctype enctypes[] = { ENCTYPE_DES_CBC_CRC,
|
|
|
f762fea |
- ENCTYPE_DES_CBC_MD5,
|
|
|
f762fea |
- ENCTYPE_DES_CBC_MD4 };
|
|
|
f762fea |
- int num_enctypes = sizeof(enctypes) / sizeof(enctypes[0]);
|
|
|
f762fea |
-
|
|
|
f762fea |
- /* We only care about getting a krb5 cred */
|
|
|
f762fea |
- desired_mechs.count = 1;
|
|
|
f762fea |
- desired_mechs.elements = &krb5oid;
|
|
|
f762fea |
-
|
|
|
f762fea |
- maj_stat = gss_acquire_cred(&min_stat, NULL, 0,
|
|
|
f762fea |
- &desired_mechs, GSS_C_INITIATE,
|
|
|
f762fea |
- &credh, NULL, NULL);
|
|
|
f762fea |
-
|
|
|
f762fea |
- if (maj_stat != GSS_S_COMPLETE) {
|
|
|
f762fea |
- if (get_verbosity() > 0)
|
|
|
f762fea |
- pgsserr("gss_acquire_cred",
|
|
|
f762fea |
- maj_stat, min_stat, &krb5oid);
|
|
|
f762fea |
- return -1;
|
|
|
f762fea |
- }
|
|
|
f762fea |
-
|
|
|
f762fea |
- maj_stat = gss_set_allowable_enctypes(&min_stat, credh, &krb5oid,
|
|
|
f762fea |
- num_enctypes, &enctypes);
|
|
|
f762fea |
- if (maj_stat != GSS_S_COMPLETE) {
|
|
|
f762fea |
- pgsserr("gss_set_allowable_enctypes",
|
|
|
f762fea |
- maj_stat, min_stat, &krb5oid);
|
|
|
f762fea |
- gss_release_cred(&min_stat, &credh);
|
|
|
f762fea |
- return -1;
|
|
|
f762fea |
- }
|
|
|
f762fea |
- sec->cred = credh;
|
|
|
f762fea |
-
|
|
|
f762fea |
- return 0;
|
|
|
f762fea |
-}
|
|
|
f762fea |
-#endif /* HAVE_SET_ALLOWABLE_ENCTYPES */
|
|
|
f762fea |
-
|
|
|
f762fea |
/*
|
|
|
f762fea |
* Obtain credentials via a key in the keytab given
|
|
|
f762fea |
* a keytab handle and a gssd_k5_kt_princ structure.
|
|
|
f762fea |
@@ -1304,3 +1249,68 @@ gssd_k5_get_default_realm(char **def_realm)
|
|
|
f762fea |
|
|
|
f762fea |
krb5_free_context(context);
|
|
|
f762fea |
}
|
|
|
f762fea |
+
|
|
|
f762fea |
+#ifdef HAVE_SET_ALLOWABLE_ENCTYPES
|
|
|
f762fea |
+/*
|
|
|
f762fea |
+ * this routine obtains a credentials handle via gss_acquire_cred()
|
|
|
f762fea |
+ * then calls gss_krb5_set_allowable_enctypes() to limit the encryption
|
|
|
f762fea |
+ * types negotiated.
|
|
|
f762fea |
+ *
|
|
|
f762fea |
+ * XXX Should call some function to determine the enctypes supported
|
|
|
f762fea |
+ * by the kernel. (Only need to do that once!)
|
|
|
f762fea |
+ *
|
|
|
f762fea |
+ * Returns:
|
|
|
f762fea |
+ * 0 => all went well
|
|
|
f762fea |
+ * -1 => there was an error
|
|
|
f762fea |
+ */
|
|
|
f762fea |
+
|
|
|
f762fea |
+int
|
|
|
f762fea |
+limit_krb5_enctypes(struct rpc_gss_sec *sec, uid_t uid)
|
|
|
f762fea |
+{
|
|
|
f762fea |
+ u_int maj_stat, min_stat;
|
|
|
f762fea |
+ gss_cred_id_t credh;
|
|
|
f762fea |
+ gss_OID_set_desc desired_mechs;
|
|
|
f762fea |
+ krb5_enctype enctypes[] = { ENCTYPE_DES_CBC_CRC,
|
|
|
f762fea |
+ ENCTYPE_DES_CBC_MD5,
|
|
|
f762fea |
+ ENCTYPE_DES_CBC_MD4 };
|
|
|
f762fea |
+ int num_enctypes = sizeof(enctypes) / sizeof(enctypes[0]);
|
|
|
f762fea |
+ extern int num_krb5_enctypes;
|
|
|
f762fea |
+ extern krb5_enctype *krb5_enctypes;
|
|
|
f762fea |
+
|
|
|
f762fea |
+ /* We only care about getting a krb5 cred */
|
|
|
f762fea |
+ desired_mechs.count = 1;
|
|
|
f762fea |
+ desired_mechs.elements = &krb5oid;
|
|
|
f762fea |
+
|
|
|
f762fea |
+ maj_stat = gss_acquire_cred(&min_stat, NULL, 0,
|
|
|
f762fea |
+ &desired_mechs, GSS_C_INITIATE,
|
|
|
f762fea |
+ &credh, NULL, NULL);
|
|
|
f762fea |
+
|
|
|
f762fea |
+ if (maj_stat != GSS_S_COMPLETE) {
|
|
|
f762fea |
+ if (get_verbosity() > 0)
|
|
|
f762fea |
+ pgsserr("gss_acquire_cred",
|
|
|
f762fea |
+ maj_stat, min_stat, &krb5oid);
|
|
|
f762fea |
+ return -1;
|
|
|
f762fea |
+ }
|
|
|
f762fea |
+
|
|
|
f762fea |
+ /*
|
|
|
f762fea |
+ * If we failed for any reason to produce global
|
|
|
f762fea |
+ * list of supported enctypes, use local default here.
|
|
|
f762fea |
+ */
|
|
|
f762fea |
+ if (krb5_enctypes == NULL)
|
|
|
f762fea |
+ maj_stat = gss_set_allowable_enctypes(&min_stat, credh,
|
|
|
f762fea |
+ &krb5oid, num_enctypes, enctypes);
|
|
|
f762fea |
+ else
|
|
|
f762fea |
+ maj_stat = gss_set_allowable_enctypes(&min_stat, credh,
|
|
|
f762fea |
+ &krb5oid, num_krb5_enctypes, krb5_enctypes);
|
|
|
f762fea |
+
|
|
|
f762fea |
+ if (maj_stat != GSS_S_COMPLETE) {
|
|
|
f762fea |
+ pgsserr("gss_set_allowable_enctypes",
|
|
|
f762fea |
+ maj_stat, min_stat, &krb5oid);
|
|
|
f762fea |
+ gss_release_cred(&min_stat, &credh);
|
|
|
f762fea |
+ return -1;
|
|
|
f762fea |
+ }
|
|
|
f762fea |
+ sec->cred = credh;
|
|
|
f762fea |
+
|
|
|
f762fea |
+ return 0;
|
|
|
f762fea |
+}
|
|
|
f762fea |
+#endif /* HAVE_SET_ALLOWABLE_ENCTYPES */
|