[SCM] Samba Shared Repository - branch v3-3-test updated
Karolin Seeger
kseeger at samba.org
Fri Oct 16 07:05:35 MDT 2009
The branch, v3-3-test has been updated
via 6eacb25... cifs.upcall: do a brute-force search for KRB5 credcache
via 6aa0f05... cifs.upcall: make using ip address conditional on new option
via 8fed5de... cifs.upcall: switch to getopt_long
via 177e543... cifs.upcall: fix IPv6 addrs sent to upcall to have colon delimiters
via ff1b2c8... cifs.upcall: use ip address passed by kernel to get server's hostname
via fe57399... cifs.upcall: clean up flag handling
via e919c3a... cifs.upcall: try getting a "cifs/" principal and fall back to "host/"
via 0b516e8... cifs.upcall: declare a structure for holding decoded args
via 56de963... cifs.upcall: formatting cleanup
via e9b932b... cifs.upcall: clean up logging and add debug messages
via 223bee1... Attempt to fix the build -- jlayton, please check!
via 9ecd9e7... cifs.upcall: use pid value from kernel to determine KRB5CCNAME to use
from 96b600d... s3:winbind: Fix bug 6793 -- segfault in winbindd_pam_auth
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-3-test
- Log -----------------------------------------------------------------
commit 6eacb25d736d47e1b4572aec5a143b15fbed619e
Author: Jeff Layton <jlayton at redhat.com>
Date: Wed Oct 14 11:06:23 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 6aa0f05509ec1b8578021051f83627f4ca296ef8
Author: Jeff Layton <jlayton at redhat.com>
Date: Wed Oct 14 11:06:21 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 8fed5de25979654baf1c62b0346c725b9c6b6866
Author: Jeff Layton <jlayton at redhat.com>
Date: Wed Oct 14 11:06:20 2009 -0400
cifs.upcall: switch to getopt_long
...to allow long option names.
Signed-off-by: Jeff Layton <jlayton at redhat.com>
commit 177e5437a75267fdfce8ba693f039a10344e5974
Author: Jeff Layton <jlayton at redhat.com>
Date: Wed Oct 14 11:06:19 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 ff1b2c8725e21ed7fc944020a1c1cc12a80a9bec
Author: Jeff Layton <jlayton at redhat.com>
Date: Wed Oct 14 11:06:18 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 fe57399ac4ddbdc601871579478b996cfc85fcee
Author: Jeff Layton <jlayton at redhat.com>
Date: Wed Oct 14 11:04:58 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 e919c3ac1229eae35614b92a9daebc71e770ca1b
Author: Jeff Layton <jlayton at redhat.com>
Date: Wed Oct 14 11:04:56 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 0b516e8e9e5b1c4b2ab32b27c37ec708d6afd5d2
Author: Jeff Layton <jlayton at redhat.com>
Date: Wed Oct 14 11:04:55 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 56de963329bed9a06d27d70dad1d6a21f5f9213a
Author: Jeff Layton <jlayton at redhat.com>
Date: Wed Oct 14 11:04:54 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 e9b932b242cac1061a19da9421b515cacf6c631b
Author: Jeff Layton <jlayton at redhat.com>
Date: Wed Oct 14 11:04:53 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 223bee1fc5f655adb61db603a5423c8bf4a5f582
Author: Volker Lendecke <vl at samba.org>
Date: Wed Oct 14 11:04:52 2009 -0400
Attempt to fix the build -- jlayton, please check!
commit 9ecd9e7dbd6f5f6a07614084207b4891a93ca79b
Author: Jeff Layton <jlayton at redhat.com>
Date: Wed Oct 14 11:04:50 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 +-
source/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 9782987..a60dd9d 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/source/client/cifs.upcall.c b/source/client/cifs.upcall.c
index 4110de3..71e60c6 100644
--- a/source/client/cifs.upcall.c
+++ b/source/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