[fedfs-utils] [PATCH 11/11] fedfsc: Convert fedfs-set-nsdb-params to use new libadmin API
Chuck Lever
chuck.lever at oracle.com
Mon Dec 2 12:33:53 PST 2013
Signed-off-by: Chuck Lever <chuck.lever at oracle.com>
---
doc/man/fedfs-set-nsdb-params.8 | 125 +++++++--------------
src/fedfsc/fedfs-set-nsdb-params.c | 214 +++++++++++++++++++-----------------
2 files changed, 152 insertions(+), 187 deletions(-)
diff --git a/doc/man/fedfs-set-nsdb-params.8 b/doc/man/fedfs-set-nsdb-params.8
index 78bfdf1..71bee9e 100644
--- a/doc/man/fedfs-set-nsdb-params.8
+++ b/doc/man/fedfs-set-nsdb-params.8
@@ -5,7 +5,7 @@
.\"
.\"
-.\" Copyright 2011 Oracle. All rights reserved.
+.\" Copyright 2011, 2013 Oracle. All rights reserved.
.\"
.\" This file is part of fedfs-utils.
.\"
@@ -39,6 +39,8 @@ fedfs-set-nsdb-params \- send a FEDFS_SET_NSDB_PARAMS ADMIN protocol request
.IR nsdbname ]
.RB [ \-r
.IR nsdbport ]
+.RB [ \-s
+.IR security ]
.SH INTRODUCTION
RFC 5716 introduces the Federated File System (FedFS, for short).
FedFS is an extensible standardized mechanism
@@ -122,90 +124,21 @@ Specifies the IP port of the NSDB to insert into the new FedFS junction.
If this option is not specified,
the value of the FEDFS_NSDB_PORT environment variable is consulted.
The default value if the variable is not set is 389.
-.SH EXIT CODES
-The remote administration service returns a value that reflects the
-success of the requested operation.
-.TP
-.B FEDFS_OK
-The operation succeeded.
-.TP
-.B FEDFS_ERR_ACCESS
-The caller does not have permission to perform the requested operation
-on the remote server.
-.TP
-.B FEDFS_ERR_BADCHAR
-The NSDB hostname contains a character which is not
-supported by the remote server.
-.TP
-.B FEDFS_ERR_BADXDR
-The remote server encountered an XDR decoding error while
-processing the request.
-.TP
-.B FEDFS_ERR_INVAL
-One of the arguments was not valid.
-.TP
-.B FEDFS_ERR_IO
-A hard error occurred on the remote server.
-.TP
-.B FEDFS_ERR_PERM
-The operation was not allowed because the caller is
-either not a privileged user or not the owner of an object that
-would be modified by the operation.
-.TP
-.B FEDFS_ERR_SVRFAULT
-An unanticipated non-protocol error occurred on the remote server.
-.TP
-.B FEDFS_ERR_NSDB_ROUTE
-The remote server was unable to find a route to the NSDB.
-.TP
-.B FEDFS_ERR_NSDB_DOWN
-The remote server determined that the NSDB was down.
-.TP
-.B FEDFS_ERR_NSDB_CONN
-The remote server was unable to establish a connection with the NSDB.
-.TP
-.B FEDFS_ERR_NSDB_AUTH
-The remote server was unable to authenticate
-and establish a secure connection with the NSDB.
-.TP
-.B FEDFS_ERR_NSDB_LDAP
-An LDAP error occurred on the connection between the remote server and NSDB.
-.TP
-.B FEDFS_ERR_NSDB_LDAP_VAL
-Indicates the same error as FEDFS_ERR_NSDB_LDAP,
-and allows an LDAP protocol error value to be returned to the client.
-.TP
-.B FEDFS_ERR_NSDB_RESPONSE
-The remote server received a malformed response from the NSDB.
-This includes situations when an NSDB entry (e.g. FSN or FSL)
-is missing a required attribute.
-.TP
-.B FEDFS_ERR_NSDB_FAULT
-An unanticipated error related to the NSDB occurred.
-.TP
-.B FEDFS_ERR_NSDB_PARAMS
-The remote server does not have any connection
-parameters on record for the specified NSDB.
-.TP
-.B FEDFS_ERR_NSDB_LDAP_REFERRAL
-The remote server received an LDAP referral that it was unable to follow.
-.TP
-.B FEDFS_ERR_NSDB_LDAP_REFERRAL_VAL
-Indicates the same error as FEDFS_ERR_NSDB_LDAP_REFERRAL,
-and allows an LDAP protocol error value to be returned back to the client.
-.TP
-.B FEDFS_ERR_NSDB_LDAP_REFERRAL_NOTFOLLOWED
-The remote server received an LDAP referral that it chose not to follow,
-either because the remote server does not support following LDAP referrals
-or LDAP referral following is disabled.
-.TP
-.B FEDFS_ERR_NSDB_PARAMS_LDAP_REFERRAL
-The remote server received an LDAP referral that it chose not to follow
-because the remote server had no NSDB parameters for the NSDB
-targeted by the LDAP referral.
-.TP
-.B FEDFS_ERR_NOTSUPP
-The remote server does not support the specified procedure.
+.IP "\fB\-s, \-\-security=\fIflavor\fP"
+Specifies the security flavor to use
+when contacting the remote FedFS ADMIN service.
+Valid flavors are
+.BR sys ,
+.BR unix ,
+.BR krb5 ,
+.BR krb5i ", and"
+.BR krb5p .
+If this option is not specified, the
+.B unix
+flavor is used.
+See the
+.B SECURITY
+section of this man page for details.
.SH EXAMPLES
Suppose you are the FedFS administrator of the
.I example.net
@@ -228,13 +161,33 @@ now knows about the
NSDB and can use it for resolving FedFS junctions.
It will not use TLS when querying the NSDB to resolve junctions.
.SH SECURITY
-RPCSEC GSSAPI authentication has not yet been implemented for this command.
+By default, or if the
+.B sys
+and
+.B unix
+flavors are specified with the
+.BI \-\-security= flavor
+option, the
+.BR fedfs-create-junction (8)
+command uses AUTH_SYS security for the Remote Procedure Call.
+AUTH_SYS has known weaknesses and should be avoided on untrusted networks.
+.P
+The RPC client uses the Kerberos v5 GSS mechanism
+if a Kerberos security flavor is specified.
+When specifying a Kerberos security flavor,
+the user must first obtain a valid Kerberos ticket using
+.BR kinit (1)
+before running
+.BR fedfs-create-junction (8).
+.P
+The AUTH_NONE security flavor is no longer supported by this implementation.
.SH "SEE ALSO"
.BR fedfs (7),
.BR nsdb-parameters (7),
.BR rpc.fedfsd (8),
.BR fedfs-get-nsdb-params (8),
.BR nsdbparams (8),
+.BR kinit (1),
.BR rpc (3t)
.sp
RFC 5716 for FedFS requirements and overview
diff --git a/src/fedfsc/fedfs-set-nsdb-params.c b/src/fedfsc/fedfs-set-nsdb-params.c
index 783f045..2ac3568 100644
--- a/src/fedfsc/fedfs-set-nsdb-params.c
+++ b/src/fedfsc/fedfs-set-nsdb-params.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright 2010 Oracle. All rights reserved.
+ * Copyright 2010, 2013 Oracle. All rights reserved.
*
* This file is part of fedfs-utils.
*
@@ -28,31 +28,25 @@
#include <string.h>
#include <stdbool.h>
+#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <getopt.h>
#include <locale.h>
-#include <rpc/clnt.h>
-#include <ldap.h>
-
#include "fedfs.h"
#include "fedfs_admin.h"
+#include "admin.h"
#include "nsdb.h"
#include "junction.h"
#include "xlog.h"
#include "gpl-boiler.h"
/**
- * Default RPC request timeout
- */
-static struct timeval fedfs_set_nsdb_params_timeout = { 25, 0 };
-
-/**
* Short form command line options
*/
-static const char fedfs_set_nsdb_params_opts[] = "?df:h:l:n:r:";
+static const char fedfs_set_nsdb_params_opts[] = "?df:h:l:n:r:s:";
/**
* Long form command line options
@@ -65,6 +59,7 @@ static const struct option fedfs_set_nsdb_params_longopts[] = {
{ "nsdbname", 1, NULL, 'l', },
{ "nettype", 1, NULL, 'n', },
{ "nsdbport", 1, NULL, 'r', },
+ { "security", 1, NULL, 's', },
{ NULL, 0, NULL, 0, },
};
@@ -72,8 +67,9 @@ static const struct option fedfs_set_nsdb_params_longopts[] = {
* Display program synopsis
*
* @param progname NUL-terminated C string containing name of program
+ * @return program exit status
*/
-static void
+static int
fedfs_set_nsdb_params_usage(const char *progname)
{
fprintf(stderr, "\n%s version " VERSION "\n", progname);
@@ -88,48 +84,61 @@ fedfs_set_nsdb_params_usage(const char *progname)
fprintf(stderr, "\t-h, --hostname ADMIN server hostname (default: 'localhost')\n");
fprintf(stderr, "\t-l, --nsdbname NSDB hostname to set\n");
fprintf(stderr, "\t-r, --nsdbport NSDB port to set\n");
+ fprintf(stderr, "\t-s, --security RPC security level\n");
fprintf(stderr, "%s", fedfs_gpl_boilerplate);
- exit((int)FEDFS_ERR_INVAL);
+ return EXIT_FAILURE;
}
/**
- * Construct connection parameters argument
+ * Set NSDB connection parameters on a remote fileserver
*
- * @param certfile NUL-terminated UTF-8 string containing pathname of file containing security data to send
- * @param params OUT: filled-in NSDB connection parameters to send
- * @result true if construction was successful
+ * @param host an initialized and opened admin_t
+ * @param nsdb an NSDB hostname and port to set
+ * @param cert pointer to certificate data, or NULL
+ * @return program exit status
*/
-static _Bool
-fedfs_set_nsdb_params_get_params(const char *certfile, FedFsNsdbParams *params)
+static int
+fedfs_set_nsdb_params_try(admin_t host, struct admin_nsdb *nsdb,
+ struct admin_cert *cert)
{
- FedFsStatus retval;
- unsigned int len;
- char *buf;
+ int status, err;
- if (certfile == NULL) {
- params->secType = FEDFS_SEC_NONE;
- return true;
+ if (cert == NULL)
+ err = admin_set_nsdb_params_none(host, nsdb);
+ else
+ err = admin_set_nsdb_params_tls(host, nsdb, cert);
+
+ status = EXIT_FAILURE;
+ switch (err) {
+ case 0:
+ break;
+ case EACCES:
+ xlog(L_ERROR, "%s: access denied", admin_hostname(host));
+ xlog(D_GENERAL, "%s",
+ admin_perror(host, admin_hostname(host)));
+ goto out;
+ case EIO:
+ xlog(L_ERROR, "%s",
+ admin_perror(host, admin_hostname(host)));
+ goto out;
+ default:
+ xlog(L_ERROR, "ADMIN client: %s", strerror(err));
+ goto out;
}
- retval = nsdb_connsec_read_pem_file(certfile, &buf, &len);
- switch (retval) {
+ switch (admin_status(host)) {
case FEDFS_OK:
+ printf("Parameters set successfully\n");
+ status = EXIT_SUCCESS;
break;
- case FEDFS_ERR_INVAL:
- fprintf(stderr, "Invalid certificate material\n");
- return false;
default:
- fprintf(stderr, "Failed to validate %s: %s\n",
- certfile, nsdb_display_fedfsstatus(retval));
- return false;
+ nsdb_print_fedfsstatus(status);
}
- params->secType = FEDFS_SEC_TLS;
- params->FedFsNsdbParams_u.secData.secData_len = len;
- params->FedFsNsdbParams_u.secData.secData_val = buf;
- return true;
+out:
+ return status;
}
/**
@@ -137,52 +146,40 @@ fedfs_set_nsdb_params_get_params(const char *certfile, FedFsNsdbParams *params)
*
* @param hostname NUL-terminated UTF-8 string containing ADMIN server's hostname
* @param nettype NUL-terminated C string containing nettype to use for connection
- * @param nsdbname NUL-terminated UTF-8 string containing name of NSDB node to set
- * @param nsdbport port number of NSDB node to set
- * @param certfile NUL-terminated UTF-8 string containing pathname of file containing security data to send
- * @return a FedFsStatus code
+ * @param security NUL-terminated C string containing RPC security mode
+ * @param nsdb an NSDB hostname and port
+ * @param cert pointer to certificate data, or NULL
+ * @return program exit status
*/
-static FedFsStatus
-fedfs_set_nsdb_params_call(const char *hostname, const char *nettype,
- char *nsdbname, const unsigned short nsdbport,
- const char *certfile)
+static int
+fedfs_set_nsdb_params_host(const char *hostname, const char *nettype,
+ const char *security, struct admin_nsdb *nsdb,
+ struct admin_cert *cert)
{
- FedFsSetNsdbParamsArgs arg;
- enum clnt_stat status;
- FedFsStatus result;
- CLIENT *client;
-
- memset(&arg, 0, sizeof(arg));
-
- if (!fedfs_set_nsdb_params_get_params(certfile, &arg.params))
- return FEDFS_ERR_INVAL;
-
- arg.nsdbName.hostname.utf8string_len = strlen(nsdbname);
- arg.nsdbName.hostname.utf8string_val = nsdbname;
- arg.nsdbName.port = nsdbport;
-
- client = clnt_create(hostname, FEDFS_PROG, FEDFS_V1, nettype);
- if (client == NULL) {
- clnt_pcreateerror("Failed to create FEDFS client");
- result = FEDFS_ERR_SVRFAULT;
- goto out;
+ admin_t host;
+ int status;
+
+ status = EXIT_FAILURE;
+ switch (admin_create(hostname, nettype, security, &host)) {
+ case 0:
+ status = fedfs_set_nsdb_params_try(host, nsdb, cert);
+ admin_release(host);
+ break;
+ case EINVAL:
+ xlog(L_ERROR, "Invalid command line parameter");
+ break;
+ case EACCES:
+ xlog(L_ERROR, "Failed to authenticate server");
+ break;
+ case EKEYEXPIRED:
+ xlog(L_ERROR, "User credentials not found");
+ break;
+ default:
+ xlog(L_ERROR, "%s",
+ admin_open_perror(admin_hostname(host)));
}
- memset((char *)&result, 0, sizeof(result));
- status = clnt_call(client, FEDFS_SET_NSDB_PARAMS,
- (xdrproc_t)xdr_FedFsSetNsdbParamsArgs, (caddr_t)&arg,
- (xdrproc_t)xdr_FedFsStatus, (caddr_t)&result,
- fedfs_set_nsdb_params_timeout);
- if (status != RPC_SUCCESS) {
- clnt_perror(client, "FEDFS_SET_NSDB_PARAMS call failed");
- result = FEDFS_ERR_SVRFAULT;
- } else
- nsdb_print_fedfsstatus(result);
- (void)clnt_destroy(client);
-
-out:
- free(arg.params.FedFsNsdbParams_u.secData.secData_val);
- return result;
+ return status;
}
/**
@@ -195,10 +192,9 @@ out:
int
main(int argc, char **argv)
{
- char *progname, *hostname, *nettype;
- char *nsdbname, *certfile;
- unsigned short nsdbport;
- unsigned int seconds;
+ char *progname, *hostname, *nettype, *security, *certfile;
+ struct admin_cert tmp, *cert;
+ struct admin_nsdb nsdb;
FedFsStatus status;
int arg;
@@ -216,10 +212,11 @@ main(int argc, char **argv)
xlog_syslog(0);
xlog_open(progname);
- nsdb_env(&nsdbname, &nsdbport, NULL, NULL);
+ nsdb_env((char **)&nsdb.an_hostname, &nsdb.an_port, NULL, NULL);
hostname = "localhost";
nettype = "netpath";
+ security = "unix";
certfile = NULL;
while ((arg = getopt_long(argc, argv, fedfs_set_nsdb_params_opts, fedfs_set_nsdb_params_longopts, NULL)) != -1) {
switch (arg) {
@@ -236,48 +233,63 @@ main(int argc, char **argv)
if (!nsdb_is_hostname_utf8(optarg)) {
fprintf(stderr, "NSDB name %s is "
"not a UTF-8 hostname\n", optarg);
- fedfs_set_nsdb_params_usage(progname);
+ return fedfs_set_nsdb_params_usage(progname);
}
- nsdbname = optarg;
+ nsdb.an_hostname = optarg;
break;
case 'n':
nettype = optarg;
break;
case 'r':
- if (!nsdb_parse_port_string(optarg, &nsdbport)) {
+ if (!nsdb_parse_port_string(optarg, &nsdb.an_port)) {
fprintf(stderr, "Bad port number: %s\n",
optarg);
- fedfs_set_nsdb_params_usage(progname);
+ return fedfs_set_nsdb_params_usage(progname);
}
break;
+ case 's':
+ security = optarg;
+ break;
default:
fprintf(stderr, "Invalid command line argument: %c\n", (char)arg);
case '?':
- fedfs_set_nsdb_params_usage(progname);
+ return fedfs_set_nsdb_params_usage(progname);
}
}
if (optind != argc) {
fprintf(stderr, "Unrecognized command line argument\n");
- fedfs_set_nsdb_params_usage(progname);
+ return fedfs_set_nsdb_params_usage(progname);
}
- if (nsdbname == NULL) {
+ if (nsdb.an_hostname == NULL) {
fprintf(stderr, "Missing required command line argument\n");
- fedfs_set_nsdb_params_usage(progname);
+ return fedfs_set_nsdb_params_usage(progname);
}
nsdb_connsec_crypto_startup();
- for (seconds = FEDFS_DELAY_MIN_SECS;; seconds = fedfs_delay(seconds)) {
- status = fedfs_set_nsdb_params_call(hostname, nettype,
- nsdbname, nsdbport, certfile);
- if (status != FEDFS_ERR_DELAY)
+ status = EXIT_FAILURE;
+ if (certfile != NULL) {
+ cert = &tmp;
+ status = nsdb_connsec_read_pem_file(certfile,
+ (char **)&cert->ac_data,
+ &cert->ac_len);
+ switch (status) {
+ case FEDFS_OK:
break;
+ case FEDFS_ERR_INVAL:
+ fprintf(stderr, "Invalid certificate material\n");
+ goto out;
+ default:
+ fprintf(stderr, "Failed to validate %s: %s\n",
+ certfile, nsdb_display_fedfsstatus(status));
+ goto out;
+ }
+ } else
+ cert = NULL;
- xlog(D_GENERAL, "Delaying %u seconds...", seconds);
- if (sleep(seconds) != 0)
- break;
- }
-
+ status = fedfs_set_nsdb_params_host(hostname, nettype,
+ security, &nsdb, cert);
+out:
nsdb_connsec_crypto_shutdown();
- return (int)status;
+ return status;
}
More information about the fedfs-utils-devel
mailing list