[SCM] Samba Shared Repository - branch v3-4-test updated
Karolin Seeger
kseeger at samba.org
Fri Oct 16 07:04:28 MDT 2009
The branch, v3-4-test has been updated
via 5df191a... cifs.upcall: do a brute-force search for KRB5 credcache
via f3b2402... cifs.upcall: make using ip address conditional on new option
via d95570b... cifs.upcall: switch to getopt_long
via 00f2988... cifs.upcall: fix IPv6 addrs sent to upcall to have colon delimiters
via 95d7a6d... cifs.upcall: use ip address passed by kernel to get server's hostname
via 531a2f4... cifs.upcall: clean up flag handling
via edca7df... cifs.upcall: try getting a "cifs/" principal and fall back to "host/"
via 3eac202b.. cifs.upcall: declare a structure for holding decoded args
via 8bf0837... cifs.upcall: formatting cleanup
via 7c7bb15... cifs.upcall: clean up logging and add debug messages
via 78b53b8... Attempt to fix the build -- jlayton, please check!
via 416f92e... cifs.upcall: use pid value from kernel to determine KRB5CCNAME to use
from 85ee297... Final part of fix for bug 6793 - winbindd crash with "INTERNAL ERROR: Signal 6" Don't use mapped_user uninitialized. Jeremy.
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-4-test
- Log -----------------------------------------------------------------
commit 5df191a5fdad480d00d278c7f5046c6f0b80e386
Author: Jeff Layton <jlayton at redhat.com>
Date: Wed Oct 14 10:59:00 2009 -0400
cifs.upcall: do a brute-force search for KRB5 credcache
A few weeks ago, I added some code to cifs.upcall to take the pid sent
by the kernel and use that to get the value of the $KRB5CCNAME
environment var for the process. That works fine on the initial mount,
but could be problematic on reconnect.
There's no guarantee on a reconnect that the process that initiates the
upcall will have $KRB5CCNAME pointed at the correct credcache. Because
of this, the current scheme isn't going to be reliable enough and we
need to use something different.
This patch replaces that scheme with one very similar to the one used by
rpc.gssd in nfs-utils. It searches the credcache dir (currently
hardcoded to /tmp) for a valid credcache for the given uid. If it finds
one then it uses that as the credentials cache. If it finds more than
one, it uses the one with the latest TGT expiration.
Signed-off-by: Jeff Layton <jlayton at redhat.com>
Addresses bug #6810.
commit f3b2402a737ff0a7e80a03ade9f57d65dabdc7eb
Author: Jeff Layton <jlayton at redhat.com>
Date: Wed Oct 14 10:58:56 2009 -0400
cifs.upcall: make using ip address conditional on new option
Igor Mammedov pointed out that reverse resolving an IP address to get
the hostname portion of a principal could open a possible attack
vector. If an attacker were to gain control of DNS, then he could
redirect the mount to a server of his choosing, and fix the reverse
resolution to point to a hostname of his choosing (one where he has
the key for the corresponding cifs/ or host/ principal).
That said, we often trust DNS for other reasons and it can be useful
to do so. Make the code that allows trusting DNS to be enabled by
adding --trust-dns to the cifs.upcall invocation.
Signed-off-by: Jeff Layton <jlayton at redhat.com>
commit d95570b60832e980f0ff6bad96a3a45a7ba9789a
Author: Jeff Layton <jlayton at redhat.com>
Date: Wed Oct 14 10:58:48 2009 -0400
cifs.upcall: switch to getopt_long
...to allow long option names.
Signed-off-by: Jeff Layton <jlayton at redhat.com>
commit 00f298804be8f561e6ed584fcd516634ec74c4d7
Author: Jeff Layton <jlayton at redhat.com>
Date: Wed Oct 14 10:58:48 2009 -0400
cifs.upcall: fix IPv6 addrs sent to upcall to have colon delimiters
Current kernels don't send IPv6 addresses with the colon delimiters, add
a routine to add them when they're not present.
Signed-off-by: Jeff Layton <jlayton at redhat.com>
commit 95d7a6d7699604ec1b5b0e90b341c57c2d3c55c2
Author: Jeff Layton <jlayton at redhat.com>
Date: Wed Oct 14 10:58:48 2009 -0400
cifs.upcall: use ip address passed by kernel to get server's hostname
Instead of using the hostname given by the upcall to get the server's
principal, take the IP address given in the upcall and reverse resolve
it to a hostname.
Signed-off-by: Jeff Layton <jlayton at redhat.com>
commit 531a2f482d7519122f79d9d8049a96f63d361a2f
Author: Jeff Layton <jlayton at redhat.com>
Date: Wed Oct 14 10:58:47 2009 -0400
cifs.upcall: clean up flag handling
Add a new stack var to hold the flags returned by the decoder routine
so that we don't need to worry so much about preserving "rc".
With this, we can drop privs before trying to find the location of
the credcache.
Signed-off-by: Jeff Layton <jlayton at redhat.com>
commit edca7df0dd43ee1d7ae2fc4954470efdf64a4d8e
Author: Jeff Layton <jlayton at redhat.com>
Date: Wed Oct 14 10:58:20 2009 -0400
cifs.upcall: try getting a "cifs/" principal and fall back to "host/"
cifs.upcall takes a "-c" flag that tells the upcall to get a principal
in the form of "cifs/hostname.example.com at REALM" instead of
"host/hostname.example.com at REALM". This has turned out to be a source of
great confusion for users.
Instead of requiring this flag, have the upcall try to get a "cifs/"
principal first. If that fails, fall back to getting a "host/"
principal.
Signed-off-by: Jeff Layton <jlayton at redhat.com>
commit 3eac202b211b382ebe299538647cbbd7d0c803b1
Author: Jeff Layton <jlayton at redhat.com>
Date: Wed Oct 14 10:44:40 2009 -0400
cifs.upcall: declare a structure for holding decoded args
The argument list for the decoder is becoming rather long. Declare an
args structure and use that for holding the args. This also simplifies
pointer handling a bit.
Signed-off-by: Jeff Layton <jlayton at redhat.com>
commit 8bf083788bed03fdc7b535595eea8ce83a6f15f9
Author: Jeff Layton <jlayton at redhat.com>
Date: Wed Oct 14 10:44:22 2009 -0400
cifs.upcall: formatting cleanup
Clean up some unneeded curly braces, and fix some indentation.
Signed-off-by: Jeff Layton <jlayton at redhat.com>
commit 7c7bb1572c86767658852426e6eb7de901b1cab2
Author: Jeff Layton <jlayton at redhat.com>
Date: Wed Oct 14 10:43:18 2009 -0400
cifs.upcall: clean up logging and add debug messages
Change the log levels to be more appropriate to the messages being
logged. Error messages should be LOG_ERR and not LOG_WARNING, for
instance.
Add some LOG_DEBUG messages that we can use to diagnose problems with
krb5 upcalls. With these, someone can set up syslog to log daemon.debug
and should be able to get more info when things aren't working.
Signed-off-by: Jeff Layton <jlayton at redhat.com>
commit 78b53b878a7871ea0ef311317da561008ad07e08
Author: Volker Lendecke <vl at samba.org>
Date: Wed Oct 14 10:42:46 2009 -0400
Attempt to fix the build -- jlayton, please check!
commit 416f92e3ae739d6ba6593c8e9c43192e4671fc77
Author: Jeff Layton <jlayton at redhat.com>
Date: Wed Oct 14 10:42:28 2009 -0400
cifs.upcall: use pid value from kernel to determine KRB5CCNAME to use
If the kernel sends the upcall a pid of the requesting process, we can
open that process' /proc/<pid>/environ file and scrape the KRB5CCNAME
value out of it.
Signed-off-by: Jeff Layton <jlayton at redhat.com>
-----------------------------------------------------------------------
Summary of changes:
docs-xml/manpages-3/cifs.upcall.8.xml | 19 +-
source3/client/cifs.upcall.c | 488 +++++++++++++++++++++++++--------
2 files changed, 386 insertions(+), 121 deletions(-)
Changeset truncated at 500 lines:
diff --git a/docs-xml/manpages-3/cifs.upcall.8.xml b/docs-xml/manpages-3/cifs.upcall.8.xml
index b62246c..7259b10 100644
--- a/docs-xml/manpages-3/cifs.upcall.8.xml
+++ b/docs-xml/manpages-3/cifs.upcall.8.xml
@@ -19,8 +19,8 @@
<refsynopsisdiv>
<cmdsynopsis>
<command>cifs.upcall</command>
- <arg choice="opt">-c</arg>
- <arg choice="opt">-v</arg>
+ <arg choice="opt">--trust-dns|-t</arg>
+ <arg choice="opt">--version|-v</arg>
<arg choice="req">keyid</arg>
</cmdsynopsis>
</refsynopsisdiv>
@@ -48,12 +48,17 @@ to be run that way.</para>
<variablelist>
<varlistentry>
<term>-c</term>
- <listitem><para>When handling a kerberos upcall, use a service principal that starts with "cifs/". The default is to use the "host/" service principal.
+ <listitem><para>This option is deprecated and is currently ignored.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>--trust-dns|-t</term>
+ <listitem><para>With krb5 upcalls, the name used as the host portion of the service principal defaults to the hostname portion of the UNC. This option allows the upcall program to reverse resolve the network address of the server in order to get the hostname.</para>
+ <para>This is less secure than not trusting DNS. When using this option, it's possible that an attacker could get control of DNS and trick the client into mounting a different server altogether. It's preferable to instead add server principals to the KDC for every possible hostname, but this option exists for cases where that isn't possible. The default is to not trust reverse hostname lookups in this fashion.
</para></listitem>
</varlistentry>
-
<varlistentry>
- <term>-v</term>
+ <term>--version|-v</term>
<listitem><para>Print version number and exit.
</para></listitem>
</varlistentry>
@@ -85,8 +90,8 @@ to be run that way.</para>
<para>To make this program useful for CIFS, you'll need to set up entries for them in request-key.conf<manvolnum>5</manvolnum>. Here's an example of an entry for each key type:</para>
<programlisting>
#OPERATION TYPE D C PROGRAM ARG1 ARG2...
-#========= ============= = = ==========================================
-create cifs.spnego * * /usr/local/sbin/cifs.upcall -c %k
+#========= ============= = = ================================
+create cifs.spnego * * /usr/local/sbin/cifs.upcall %k
create dns_resolver * * /usr/local/sbin/cifs.upcall %k
</programlisting>
<para>
diff --git a/source3/client/cifs.upcall.c b/source3/client/cifs.upcall.c
index 4110de3..71e60c6 100644
--- a/source3/client/cifs.upcall.c
+++ b/source3/client/cifs.upcall.c
@@ -1,6 +1,7 @@
/*
* CIFS user-space helper.
* Copyright (C) Igor Mammedov (niallain at gmail.com) 2007
+* Copyright (C) Jeff Layton (jlayton at redhat.com) 2009
*
* Used by /sbin/request-key for handling
* cifs upcall for kerberos authorization of access to share and
@@ -26,16 +27,166 @@ create dns_resolver * * /usr/local/sbin/cifs.upcall %k
#include "includes.h"
#include <keyutils.h>
+#include <getopt.h>
#include "cifs_spnego.h"
-const char *CIFSSPNEGO_VERSION = "1.2";
+#define CIFS_DEFAULT_KRB5_DIR "/tmp"
+#define CIFS_DEFAULT_KRB5_PREFIX "krb5cc_"
+
+#define MAX_CCNAME_LEN PATH_MAX + 5
+
+const char *CIFSSPNEGO_VERSION = "1.3";
static const char *prog = "cifs.upcall";
-typedef enum _secType {
+typedef enum _sectype {
NONE = 0,
KRB5,
MS_KRB5
-} secType_t;
+} sectype_t;
+
+static inline int
+k5_data_equal(krb5_data d1, krb5_data d2, unsigned int length)
+{
+ if (!length)
+ length = d1.length;
+
+ return (d1.length == length &&
+ d1.length == d2.length &&
+ memcmp(d1.data, d2.data, length) == 0);
+
+}
+
+/* does the ccache have a valid TGT? */
+static time_t
+get_tgt_time(const char *ccname) {
+ krb5_context context;
+ krb5_ccache ccache;
+ krb5_cc_cursor cur;
+ krb5_creds creds;
+ krb5_principal principal;
+ krb5_data tgt = { .data = "krbtgt",
+ .length = 6 };
+ time_t credtime = 0;
+
+ if (krb5_init_context(&context)) {
+ syslog(LOG_DEBUG, "%s: unable to init krb5 context", __func__);
+ return 0;
+ }
+
+ if (krb5_cc_resolve(context, ccname, &ccache)) {
+ syslog(LOG_DEBUG, "%s: unable to resolve krb5 cache", __func__);
+ goto err_cache;
+ }
+
+ if (krb5_cc_set_flags(context, ccache, 0)) {
+ syslog(LOG_DEBUG, "%s: unable to set flags", __func__);
+ goto err_cache;
+ }
+
+ if (krb5_cc_get_principal(context, ccache, &principal)) {
+ syslog(LOG_DEBUG, "%s: unable to get principal", __func__);
+ goto err_princ;
+ }
+
+ if (krb5_cc_start_seq_get(context, ccache, &cur)) {
+ syslog(LOG_DEBUG, "%s: unable to seq start", __func__);
+ goto err_ccstart;
+ }
+
+ while (!credtime && !krb5_cc_next_cred(context, ccache, &cur, &creds)) {
+ if (k5_data_equal(creds.server->realm, principal->realm, 0) &&
+ k5_data_equal(creds.server->data[0], tgt, tgt.length) &&
+ k5_data_equal(creds.server->data[1], principal->realm, 0) &&
+ creds.times.endtime > time(NULL))
+ credtime = creds.times.endtime;
+ krb5_free_cred_contents(context, &creds);
+ }
+ krb5_cc_end_seq_get(context, ccache, &cur);
+
+err_ccstart:
+ krb5_free_principal(context, principal);
+err_princ:
+ krb5_cc_set_flags(context, ccache, KRB5_TC_OPENCLOSE);
+ krb5_cc_close(context, ccache);
+err_cache:
+ krb5_free_context(context);
+ return credtime;
+}
+
+static int
+krb5cc_filter(const struct dirent *dirent)
+{
+ if (strstr(dirent->d_name, CIFS_DEFAULT_KRB5_PREFIX))
+ return 1;
+ else
+ return 0;
+}
+
+/* search for a credcache that looks like a likely candidate */
+static char *
+find_krb5_cc(const char *dirname, uid_t uid)
+{
+ struct dirent **namelist;
+ struct stat sbuf;
+ char ccname[MAX_CCNAME_LEN], *credpath, *best_cache = NULL;
+ int i, n;
+ time_t cred_time, best_time = 0;
+
+ n = scandir(dirname, &namelist, krb5cc_filter, NULL);
+ if (n < 0) {
+ syslog(LOG_DEBUG, "%s: scandir error on directory '%s': %s",
+ __func__, dirname, strerror(errno));
+ return NULL;
+ }
+
+ for (i = 0; i < n; i++) {
+ snprintf(ccname, sizeof(ccname), "FILE:%s/%s", dirname,
+ namelist[i]->d_name);
+ credpath = ccname + 5;
+ syslog(LOG_DEBUG, "%s: considering %s", __func__, credpath);
+
+ if (lstat(credpath, &sbuf)) {
+ syslog(LOG_DEBUG, "%s: stat error on '%s': %s",
+ __func__, credpath, strerror(errno));
+ free(namelist[i]);
+ continue;
+ }
+ if (sbuf.st_uid != uid) {
+ syslog(LOG_DEBUG, "%s: %s is owned by %u, not %u",
+ __func__, credpath, sbuf.st_uid, uid);
+ free(namelist[i]);
+ continue;
+ }
+ if (!S_ISREG(sbuf.st_mode)) {
+ syslog(LOG_DEBUG, "%s: %s is not a regular file",
+ __func__, credpath);
+ free(namelist[i]);
+ continue;
+ }
+ if (!(cred_time = get_tgt_time(ccname))) {
+ syslog(LOG_DEBUG, "%s: %s is not a valid credcache.",
+ __func__, ccname);
+ free(namelist[i]);
+ continue;
+ }
+
+ if (cred_time <= best_time) {
+ syslog(LOG_DEBUG, "%s: %s expires sooner than current "
+ "best.", __func__, ccname);
+ free(namelist[i]);
+ continue;
+ }
+
+ syslog(LOG_DEBUG, "%s: %s is valid ccache", __func__, ccname);
+ free(best_cache);
+ best_cache = SMB_STRNDUP(ccname, MAX_CCNAME_LEN);
+ best_time = cred_time;
+ free(namelist[i]);
+ }
+ free(namelist);
+
+ return best_cache;
+}
/*
* Prepares AP-REQ data for mechToken and gets session key
@@ -56,20 +207,28 @@ typedef enum _secType {
* sess_key- pointer for SessionKey data to be stored
*
* ret: 0 - success, others - failure
-*/
+ */
static int
-handle_krb5_mech(const char *oid, const char *principal,
- DATA_BLOB * secblob, DATA_BLOB * sess_key)
+handle_krb5_mech(const char *oid, const char *principal, DATA_BLOB *secblob,
+ DATA_BLOB *sess_key, const char *ccname)
{
int retval;
DATA_BLOB tkt, tkt_wrapped;
+ syslog(LOG_DEBUG, "%s: getting service ticket for %s", __func__,
+ principal);
+
/* get a kerberos ticket for the service and extract the session key */
- retval = cli_krb5_get_ticket(principal, 0,
- &tkt, sess_key, 0, NULL, NULL);
+ retval = cli_krb5_get_ticket(principal, 0, &tkt, sess_key, 0, ccname,
+ NULL);
- if (retval)
+ if (retval) {
+ syslog(LOG_DEBUG, "%s: failed to obtain service ticket (%d)",
+ __func__, retval);
return retval;
+ }
+
+ syslog(LOG_DEBUG, "%s: obtained service ticket", __func__);
/* wrap that up in a nice GSS-API wrapping */
tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
@@ -82,18 +241,27 @@ handle_krb5_mech(const char *oid, const char *principal,
return retval;
}
-#define DKD_HAVE_HOSTNAME 1
-#define DKD_HAVE_VERSION 2
-#define DKD_HAVE_SEC 4
-#define DKD_HAVE_IPV4 8
-#define DKD_HAVE_IPV6 16
-#define DKD_HAVE_UID 32
+#define DKD_HAVE_HOSTNAME 0x1
+#define DKD_HAVE_VERSION 0x2
+#define DKD_HAVE_SEC 0x4
+#define DKD_HAVE_IP 0x8
+#define DKD_HAVE_UID 0x10
+#define DKD_HAVE_PID 0x20
#define DKD_MUSTHAVE_SET (DKD_HAVE_HOSTNAME|DKD_HAVE_VERSION|DKD_HAVE_SEC)
-static int
-decode_key_description(const char *desc, int *ver, secType_t * sec,
- char **hostname, uid_t * uid)
+struct decoded_args {
+ int ver;
+ char *hostname;
+ char *ip;
+ uid_t uid;
+ pid_t pid;
+ sectype_t sec;
+};
+
+static unsigned int
+decode_key_description(const char *desc, struct decoded_args *arg)
{
+ int len;
int retval = 0;
char *pos;
const char *tkn = desc;
@@ -101,35 +269,52 @@ decode_key_description(const char *desc, int *ver, secType_t * sec,
do {
pos = index(tkn, ';');
if (strncmp(tkn, "host=", 5) == 0) {
- int len;
- if (pos == NULL) {
+ if (pos == NULL)
len = strlen(tkn);
- } else {
+ else
len = pos - tkn;
- }
+
len -= 4;
- SAFE_FREE(*hostname);
- *hostname = SMB_XMALLOC_ARRAY(char, len);
- strlcpy(*hostname, tkn + 5, len);
+ SAFE_FREE(arg->hostname);
+ arg->hostname = SMB_XMALLOC_ARRAY(char, len);
+ strlcpy(arg->hostname, tkn + 5, len);
retval |= DKD_HAVE_HOSTNAME;
- } else if (strncmp(tkn, "ipv4=", 5) == 0) {
- /* BB: do we need it if we have hostname already? */
- } else if (strncmp(tkn, "ipv6=", 5) == 0) {
- /* BB: do we need it if we have hostname already? */
+ } else if (!strncmp(tkn, "ip4=", 4) ||
+ !strncmp(tkn, "ip6=", 4)) {
+ if (pos == NULL)
+ len = strlen(tkn);
+ else
+ len = pos - tkn;
+
+ len -= 3;
+ SAFE_FREE(arg->ip);
+ arg->ip = SMB_XMALLOC_ARRAY(char, len);
+ strlcpy(arg->ip, tkn + 4, len);
+ retval |= DKD_HAVE_IP;
+ } else if (strncmp(tkn, "pid=", 4) == 0) {
+ errno = 0;
+ arg->pid = strtol(tkn + 4, NULL, 0);
+ if (errno != 0) {
+ syslog(LOG_ERR, "Invalid pid format: %s",
+ strerror(errno));
+ return 1;
+ } else {
+ retval |= DKD_HAVE_PID;
+ }
} else if (strncmp(tkn, "sec=", 4) == 0) {
if (strncmp(tkn + 4, "krb5", 4) == 0) {
retval |= DKD_HAVE_SEC;
- *sec = KRB5;
+ arg->sec = KRB5;
} else if (strncmp(tkn + 4, "mskrb5", 6) == 0) {
retval |= DKD_HAVE_SEC;
- *sec = MS_KRB5;
+ arg->sec = MS_KRB5;
}
} else if (strncmp(tkn, "uid=", 4) == 0) {
errno = 0;
- *uid = strtol(tkn + 4, NULL, 16);
+ arg->uid = strtol(tkn + 4, NULL, 16);
if (errno != 0) {
- syslog(LOG_WARNING, "Invalid uid format: %s",
+ syslog(LOG_ERR, "Invalid uid format: %s",
strerror(errno));
return 1;
} else {
@@ -137,10 +322,9 @@ decode_key_description(const char *desc, int *ver, secType_t * sec,
}
} else if (strncmp(tkn, "ver=", 4) == 0) { /* if version */
errno = 0;
- *ver = strtol(tkn + 4, NULL, 16);
+ arg->ver = strtol(tkn + 4, NULL, 16);
if (errno != 0) {
- syslog(LOG_WARNING,
- "Invalid version format: %s",
+ syslog(LOG_ERR, "Invalid version format: %s",
strerror(errno));
return 1;
} else {
@@ -166,7 +350,7 @@ cifs_resolver(const key_serial_t key, const char *key_descr)
for (c = 1; c <= 4; c++) {
keyend = index(keyend+1, ';');
if (!keyend) {
- syslog(LOG_WARNING, "invalid key description: %s",
+ syslog(LOG_ERR, "invalid key description: %s",
key_descr);
return 1;
}
@@ -176,20 +360,19 @@ cifs_resolver(const key_serial_t key, const char *key_descr)
/* resolve name to ip */
c = getaddrinfo(keyend, NULL, NULL, &addr);
if (c) {
- syslog(LOG_WARNING, "unable to resolve hostname: %s [%s]",
+ syslog(LOG_ERR, "unable to resolve hostname: %s [%s]",
keyend, gai_strerror(c));
return 1;
}
/* conver ip to string form */
- if (addr->ai_family == AF_INET) {
+ if (addr->ai_family == AF_INET)
p = &(((struct sockaddr_in *)addr->ai_addr)->sin_addr);
- } else {
+ else
p = &(((struct sockaddr_in6 *)addr->ai_addr)->sin6_addr);
- }
+
if (!inet_ntop(addr->ai_family, p, ip, sizeof(ip))) {
- syslog(LOG_WARNING, "%s: inet_ntop: %s",
- __FUNCTION__, strerror(errno));
+ syslog(LOG_ERR, "%s: inet_ntop: %s", __func__, strerror(errno));
freeaddrinfo(addr);
return 1;
}
@@ -197,8 +380,8 @@ cifs_resolver(const key_serial_t key, const char *key_descr)
/* setup key */
c = keyctl_instantiate(key, ip, strlen(ip)+1, 0);
if (c == -1) {
- syslog(LOG_WARNING, "%s: keyctl_instantiate: %s",
- __FUNCTION__, strerror(errno));
+ syslog(LOG_ERR, "%s: keyctl_instantiate: %s", __func__,
+ strerror(errno));
freeaddrinfo(addr);
return 1;
}
@@ -207,44 +390,106 @@ cifs_resolver(const key_serial_t key, const char *key_descr)
return 0;
}
+/*
+ * Older kernels sent IPv6 addresses without colons. Well, at least
+ * they're fixed-length strings. Convert these addresses to have colon
+ * delimiters to make getaddrinfo happy.
+ */
+static void
+convert_inet6_addr(const char *from, char *to)
+{
+ int i = 1;
+
+ while (*from) {
+ *to++ = *from++;
+ if (!(i++ % 4) && *from)
+ *to++ = ':';
+ }
+ *to = 0;
+}
+
+static int
+ip_to_fqdn(const char *addrstr, char *host, size_t hostlen)
+{
+ int rc;
+ struct addrinfo hints = { .ai_flags = AI_NUMERICHOST };
+ struct addrinfo *res;
+ const char *ipaddr = addrstr;
+ char converted[INET6_ADDRSTRLEN + 1];
+
+ if ((strlen(ipaddr) > INET_ADDRSTRLEN) && !strchr(ipaddr, ':')) {
+ convert_inet6_addr(ipaddr, converted);
+ ipaddr = converted;
+ }
+
+ rc = getaddrinfo(ipaddr, NULL, &hints, &res);
+ if (rc) {
+ syslog(LOG_DEBUG, "%s: failed to resolve %s to "
+ "ipaddr: %s", __func__, ipaddr,
+ rc == EAI_SYSTEM ? strerror(errno) : gai_strerror(rc));
+ return rc;
+ }
+
+ rc = getnameinfo(res->ai_addr, res->ai_addrlen, host, hostlen,
+ NULL, 0, NI_NAMEREQD);
+ freeaddrinfo(res);
+ if (rc) {
+ syslog(LOG_DEBUG, "%s: failed to resolve %s to fqdn: %s",
+ __func__, ipaddr,
+ rc == EAI_SYSTEM ? strerror(errno) : gai_strerror(rc));
+ return rc;
+ }
+
+ syslog(LOG_DEBUG, "%s: resolved %s to %s", __func__, ipaddr, host);
+ return 0;
+}
+
static void
usage(void)
{
- syslog(LOG_WARNING, "Usage: %s [-c] [-v] key_serial", prog);
- fprintf(stderr, "Usage: %s [-c] [-v] key_serial\n", prog);
+ syslog(LOG_INFO, "Usage: %s [-t] [-v] key_serial", prog);
+ fprintf(stderr, "Usage: %s [-t] [-v] key_serial\n", prog);
}
+const struct option long_options[] = {
+ { "trust-dns", 0, NULL, 't' },
+ { "version", 0, NULL, 'v' },
+ { NULL, 0, NULL, 0 }
+};
--
Samba Shared Repository
More information about the samba-cvs
mailing list