Message ID | 1470950774-3649-1-git-send-email-steved@redhat.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Hey Steve- Sorry for the delay, and thanks for putting this together! > On Aug 11, 2016, at 5:26 PM, Steve Dickson <SteveD@redhat.com> wrote: > > In domain_from_dns(), when at the hostname is a FQHN > query the DNS server for the _nfsv4idmapdomain TXT > record. If the record exists, use that as the > NFSv4 domain. > > Note, this query will only happen if the domain name > is not set in the /etc/idmapd.conf Is there a man page update that goes with this? The order in which the library searches for the domain name should be documented. idmapd.conf(5), maybe. Also, some indication of when a change to the TXT record can be observed by users could be mentioned. I recall that the server-side ID mapper is a little different than the client side. Does this TXT record affect server idmapper behavior too? If so, when does a TXT record change take effect? Each time nfsidmap is invoked, it will now fire off a DNS lookup. That might have performance implications, but of course the fix is to ensure the domain is set locally. Can that DNS lookup ever happen before the network is up? > Signed-off-by: Steve Dickson <steved@redhat.com> > --- > libnfsidmap.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- > 1 file changed, 103 insertions(+), 1 deletion(-) > > diff --git a/libnfsidmap.c b/libnfsidmap.c > index 2db4d13..7b8c0ed 100644 > --- a/libnfsidmap.c > +++ b/libnfsidmap.c > @@ -53,6 +53,10 @@ > #include <stdarg.h> > #include <dlfcn.h> > #include <ctype.h> > +#include <resolv.h> > +#include <arpa/nameser.h> > +#include <arpa/nameser_compat.h> > + > #include "nfsidmap.h" > #include "nfsidmap_internal.h" > #include "cfg.h" > @@ -79,6 +83,11 @@ gid_t nobody_gid = (gid_t)-1; > #define IDMAPD_DEFAULT_DOMAIN "localdomain" > #endif > > +#ifndef NFS4DNSTXTREC > +#define NFS4DNSTXTREC "_nfsv4idmapdomain" > +#endif > + > + > /* Default logging fuction */ > static void default_logger(const char *fmt, ...) > { > @@ -114,6 +123,93 @@ static int id_as_chars(char *name, uid_t *id) > return 1; > } > > +static int dns_txt_query(char *domain, char **nfs4domain) > +{ > + char *txtname = NFS4DNSTXTREC; > + char *msg, *answ, *eom, *mptr; > + int len, status = -1; > + HEADER *hdr; > + > + msg = calloc(1, NS_MAXMSG); > + if (msg == NULL) > + return -1; > + > + answ = calloc(1, NS_MAXMSG); > + if (answ == NULL) { > + free(msg); > + return -1; > + } > + > + if (res_init() < 0) { > + IDMAP_LOG(2, ("libnfsidmap: res_init() failed for %s.%s: %s\n", > + txtname, domain, hstrerror(h_errno))); > + goto freemem; > + } > + len = res_querydomain(txtname, domain, C_IN, T_TXT, msg, NS_MAXMSG); > + if (len < 0) { > + IDMAP_LOG(2, ("libnfsidmap: res_querydomain() failed for %s.%s: %s\n", > + txtname, domain, hstrerror(h_errno))); > + goto freemem; > + } > + hdr = (HEADER *)msg; > + > + /* See if there is an answer */ > + if (ntohs(hdr->ancount) < 1) { > + IDMAP_LOG(2, ("libnfsidmap: No TXT record for %s.%s\n", > + txtname, domain)); > + goto freemem; > + } > + /* find the EndOfMessage */ > + eom = msg + len; > + > + /* skip header */ > + mptr = &msg[HFIXEDSZ]; > + > + /* skip name field in question section */ > + mptr += dn_skipname(mptr, eom) + QFIXEDSZ; > + > + /* read in the question */ > + len = dn_expand(msg, eom, mptr, answ, NS_MAXDNAME); > + if (len < 0) { /* does this really matter?? */ > + IDMAP_LOG(2, ("libnfsidmap: No question section for %s.%s: %s\n", > + txtname, domain, hstrerror(h_errno))); > + goto freemem; > + } > + > + /* > + * Now, dissect the answer section, Note: if there > + * are more than one answer only the first > + * one will be used. > + */ > + > + /* skip passed the name field */ > + mptr += dn_skipname(mptr, eom); > + /* skip pass the type class and ttl fields */ > + mptr += 2 + 2 + 4; > + > + /* make sure there is some data */ > + GETSHORT(len, mptr); > + if (len < 0) { > + IDMAP_LOG(2, ("libnfsidmap: No data in answer for %s.%s\n", > + txtname, domain)); > + goto freemem; > + } > + /* get the lenght field */ > + len = (int)*mptr++; > + /* copy the data */ > + memcpy(answ, mptr, len); > + answ[len] = '\0'; > + > + *nfs4domain = strdup(answ); > + status = 0; > + > +freemem: > + free(msg); > + free(answ); > + > + return (status); > +} > + > static int domain_from_dns(char **domain) > { > struct hostent *he; > @@ -125,7 +221,13 @@ static int domain_from_dns(char **domain) > return -1; > if ((c = strchr(he->h_name, '.')) == NULL || *++c == '\0') > return -1; > - *domain = strdup(c); > + /* > + * Query DNS to see if the _nfsv4idmapdomain TXT record exists > + * If so use it... > + */ > + if (dns_txt_query(c, domain) < 0) > + *domain = strdup(c); > + > return 0; > } > > -- > 2.7.4 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-nfs" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- Chuck Lever -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On 08/14/2016 02:59 PM, Chuck Lever wrote: > Hey Steve- > > Sorry for the delay, and thanks for putting this together! > > >> On Aug 11, 2016, at 5:26 PM, Steve Dickson <SteveD@redhat.com> wrote: >> >> In domain_from_dns(), when at the hostname is a FQHN >> query the DNS server for the _nfsv4idmapdomain TXT >> record. If the record exists, use that as the >> NFSv4 domain. >> >> Note, this query will only happen if the domain name >> is not set in the /etc/idmapd.conf > > Is there a man page update that goes with this? The order in > which the library searches for the domain name should be > documented. idmapd.conf(5), maybe. Yes... I should have made this an RFC patch since I just wanted to get core out there for for comments... The man page needs to updated as well as the configure.ac. > > Also, some indication of when a change to the TXT record can > be observed by users could be mentioned. I'm not sure what you are asking here... There is the TTL time for TXT that is returned in the query but that is completely controlled by the admin... > > I recall that the server-side ID mapper is a little different > than the client side. Does this TXT record affect server > idmapper behavior too? Yes rpc.idmapd and nfsidmap use the same code to resolve the nfsv4 domain > If so, when does a TXT record change take effect? When the system admin changes it?? ;-) > > Each time nfsidmap is invoked, it will now fire off a DNS > lookup. That might have performance implications, but of > course the fix is to ensure the domain is set locally. Yeah it would be nice if the resolver API cached results but I don't think that happens and I don't think we want to build in a cache in the libnfsidmap code... > > Can that DNS lookup ever happen before the network is up? I don't think so with systemd but if the network is down there will be a lot other systems hung waiting on DNS queries... steved. > > >> Signed-off-by: Steve Dickson <steved@redhat.com> >> --- >> libnfsidmap.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- >> 1 file changed, 103 insertions(+), 1 deletion(-) >> >> diff --git a/libnfsidmap.c b/libnfsidmap.c >> index 2db4d13..7b8c0ed 100644 >> --- a/libnfsidmap.c >> +++ b/libnfsidmap.c >> @@ -53,6 +53,10 @@ >> #include <stdarg.h> >> #include <dlfcn.h> >> #include <ctype.h> >> +#include <resolv.h> >> +#include <arpa/nameser.h> >> +#include <arpa/nameser_compat.h> >> + >> #include "nfsidmap.h" >> #include "nfsidmap_internal.h" >> #include "cfg.h" >> @@ -79,6 +83,11 @@ gid_t nobody_gid = (gid_t)-1; >> #define IDMAPD_DEFAULT_DOMAIN "localdomain" >> #endif >> >> +#ifndef NFS4DNSTXTREC >> +#define NFS4DNSTXTREC "_nfsv4idmapdomain" >> +#endif >> + >> + >> /* Default logging fuction */ >> static void default_logger(const char *fmt, ...) >> { >> @@ -114,6 +123,93 @@ static int id_as_chars(char *name, uid_t *id) >> return 1; >> } >> >> +static int dns_txt_query(char *domain, char **nfs4domain) >> +{ >> + char *txtname = NFS4DNSTXTREC; >> + char *msg, *answ, *eom, *mptr; >> + int len, status = -1; >> + HEADER *hdr; >> + >> + msg = calloc(1, NS_MAXMSG); >> + if (msg == NULL) >> + return -1; >> + >> + answ = calloc(1, NS_MAXMSG); >> + if (answ == NULL) { >> + free(msg); >> + return -1; >> + } >> + >> + if (res_init() < 0) { >> + IDMAP_LOG(2, ("libnfsidmap: res_init() failed for %s.%s: %s\n", >> + txtname, domain, hstrerror(h_errno))); >> + goto freemem; >> + } >> + len = res_querydomain(txtname, domain, C_IN, T_TXT, msg, NS_MAXMSG); >> + if (len < 0) { >> + IDMAP_LOG(2, ("libnfsidmap: res_querydomain() failed for %s.%s: %s\n", >> + txtname, domain, hstrerror(h_errno))); >> + goto freemem; >> + } >> + hdr = (HEADER *)msg; >> + >> + /* See if there is an answer */ >> + if (ntohs(hdr->ancount) < 1) { >> + IDMAP_LOG(2, ("libnfsidmap: No TXT record for %s.%s\n", >> + txtname, domain)); >> + goto freemem; >> + } >> + /* find the EndOfMessage */ >> + eom = msg + len; >> + >> + /* skip header */ >> + mptr = &msg[HFIXEDSZ]; >> + >> + /* skip name field in question section */ >> + mptr += dn_skipname(mptr, eom) + QFIXEDSZ; >> + >> + /* read in the question */ >> + len = dn_expand(msg, eom, mptr, answ, NS_MAXDNAME); >> + if (len < 0) { /* does this really matter?? */ >> + IDMAP_LOG(2, ("libnfsidmap: No question section for %s.%s: %s\n", >> + txtname, domain, hstrerror(h_errno))); >> + goto freemem; >> + } >> + >> + /* >> + * Now, dissect the answer section, Note: if there >> + * are more than one answer only the first >> + * one will be used. >> + */ >> + >> + /* skip passed the name field */ >> + mptr += dn_skipname(mptr, eom); >> + /* skip pass the type class and ttl fields */ >> + mptr += 2 + 2 + 4; >> + >> + /* make sure there is some data */ >> + GETSHORT(len, mptr); >> + if (len < 0) { >> + IDMAP_LOG(2, ("libnfsidmap: No data in answer for %s.%s\n", >> + txtname, domain)); >> + goto freemem; >> + } >> + /* get the lenght field */ >> + len = (int)*mptr++; >> + /* copy the data */ >> + memcpy(answ, mptr, len); >> + answ[len] = '\0'; >> + >> + *nfs4domain = strdup(answ); >> + status = 0; >> + >> +freemem: >> + free(msg); >> + free(answ); >> + >> + return (status); >> +} >> + >> static int domain_from_dns(char **domain) >> { >> struct hostent *he; >> @@ -125,7 +221,13 @@ static int domain_from_dns(char **domain) >> return -1; >> if ((c = strchr(he->h_name, '.')) == NULL || *++c == '\0') >> return -1; >> - *domain = strdup(c); >> + /* >> + * Query DNS to see if the _nfsv4idmapdomain TXT record exists >> + * If so use it... >> + */ >> + if (dns_txt_query(c, domain) < 0) >> + *domain = strdup(c); >> + >> return 0; >> } >> >> -- >> 2.7.4 >> >> -- >> To unsubscribe from this list: send the line "unsubscribe linux-nfs" in >> the body of a message to majordomo@vger.kernel.org >> More majordomo info at http://vger.kernel.org/majordomo-info.html > > -- > Chuck Lever > > > -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
> On Aug 15, 2016, at 10:57 AM, Steve Dickson <SteveD@redhat.com> wrote: > > > > On 08/14/2016 02:59 PM, Chuck Lever wrote: >> Hey Steve- >> >> Sorry for the delay, and thanks for putting this together! >> >> >>> On Aug 11, 2016, at 5:26 PM, Steve Dickson <SteveD@redhat.com> wrote: >>> >>> In domain_from_dns(), when at the hostname is a FQHN >>> query the DNS server for the _nfsv4idmapdomain TXT >>> record. If the record exists, use that as the >>> NFSv4 domain. >>> >>> Note, this query will only happen if the domain name >>> is not set in the /etc/idmapd.conf >> >> Is there a man page update that goes with this? The order in >> which the library searches for the domain name should be >> documented. idmapd.conf(5), maybe. > Yes... I should have made this an RFC patch since I just > wanted to get core out there for for comments... > The man page needs to updated as well as the configure.ac. To enable this feature IMO a better choice is to use a command line option on nfsidmap and rpc.idmapd. >> Also, some indication of when a change to the TXT record can >> be observed by users could be mentioned. > I'm not sure what you are asking here... There is the TTL time > for TXT that is returned in the query but that is completely > controlled by the admin... Mostly this is about what might go into a man page update. After the TXT record is changed, how long before the client moves a mapped user ID from the old domain to the new one? How long before all the mapped user IDs are converted to the new domain? (I think I know the answer, but what should the man page say about it). For instance, the kernel's cache of keys delays the effect of changing the result of that TXT query. Should the man page recommend a flush of that cache on clients? -- Chuck Lever -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On 08/15/2016 11:16 AM, Chuck Lever wrote: > >> On Aug 15, 2016, at 10:57 AM, Steve Dickson <SteveD@redhat.com> wrote: >> >> >> >> On 08/14/2016 02:59 PM, Chuck Lever wrote: >>> Hey Steve- >>> >>> Sorry for the delay, and thanks for putting this together! >>> >>> >>>> On Aug 11, 2016, at 5:26 PM, Steve Dickson <SteveD@redhat.com> wrote: >>>> >>>> In domain_from_dns(), when at the hostname is a FQHN >>>> query the DNS server for the _nfsv4idmapdomain TXT >>>> record. If the record exists, use that as the >>>> NFSv4 domain. >>>> >>>> Note, this query will only happen if the domain name >>>> is not set in the /etc/idmapd.conf >>> >>> Is there a man page update that goes with this? The order in >>> which the library searches for the domain name should be >>> documented. idmapd.conf(5), maybe. >> Yes... I should have made this an RFC patch since I just >> wanted to get core out there for for comments... >> The man page needs to updated as well as the configure.ac. > > To enable this feature IMO a better choice is to use a command > line option on nfsidmap and rpc.idmapd. With Solaris, is this on by default or off? If needed.. (a big if) I think I would rather have a way to disable it. > > >>> Also, some indication of when a change to the TXT record can >>> be observed by users could be mentioned. >> I'm not sure what you are asking here... There is the TTL time >> for TXT that is returned in the query but that is completely >> controlled by the admin... > > Mostly this is about what might go into a man page update. > > After the TXT record is changed, how long before the client > moves a mapped user ID from the old domain to the new one? From a DNS standpoint all depends on the TTL on the TXT record From an NFS standpoint the next call to DNS. > How long before all the mapped user IDs are converted to the new > domain? (I think I know the answer, but what should the man > page say about it). The keys all have timeouts on them... so when they timeout... I guess maybe the key chain can be invalidate when a change is noticed? That would be easy with a daemon not so easy with a command. > > For instance, the kernel's cache of keys delays the effect of > changing the result of that TXT query. Should the man page > recommend a flush of that cache on clients? Hmm... adding a second step.. it probably should be automatic. steved. > > > -- > Chuck Lever > > > -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
> On Aug 15, 2016, at 1:00 PM, Steve Dickson <SteveD@redhat.com> wrote: > > > > On 08/15/2016 11:16 AM, Chuck Lever wrote: >> >>> On Aug 15, 2016, at 10:57 AM, Steve Dickson <SteveD@redhat.com> wrote: >>> >>> >>> >>> On 08/14/2016 02:59 PM, Chuck Lever wrote: >>>> Hey Steve- >>>> >>>> Sorry for the delay, and thanks for putting this together! >>>> >>>> >>>>> On Aug 11, 2016, at 5:26 PM, Steve Dickson <SteveD@redhat.com> wrote: >>>>> >>>>> In domain_from_dns(), when at the hostname is a FQHN >>>>> query the DNS server for the _nfsv4idmapdomain TXT >>>>> record. If the record exists, use that as the >>>>> NFSv4 domain. >>>>> >>>>> Note, this query will only happen if the domain name >>>>> is not set in the /etc/idmapd.conf >>>> >>>> Is there a man page update that goes with this? The order in >>>> which the library searches for the domain name should be >>>> documented. idmapd.conf(5), maybe. >>> Yes... I should have made this an RFC patch since I just >>> wanted to get core out there for for comments... >>> The man page needs to updated as well as the configure.ac. >> >> To enable this feature IMO a better choice is to use a command >> line option on nfsidmap and rpc.idmapd. > With Solaris, is this on by default or off? If needed.. (a big if) > I think I would rather have a way to disable it. In Solaris I don't know if there's even a way to turn it off, but specifying the domain name locally seems like it would be an effective way to prevent the TXT query. So, maybe there's no need for any command line control? I was just guessing at what you had in mind for configure.ac. >>>> Also, some indication of when a change to the TXT record can >>>> be observed by users could be mentioned. >>> I'm not sure what you are asking here... There is the TTL time >>> for TXT that is returned in the query but that is completely >>> controlled by the admin... >> >> Mostly this is about what might go into a man page update. >> >> After the TXT record is changed, how long before the client >> moves a mapped user ID from the old domain to the new one? > From a DNS standpoint all depends on the TTL on the TXT record > From an NFS standpoint the next call to DNS. Point is, it's not immediate: from questions I've gotten from Solaris testers about Linux idmapping, I expect to see one or two about "how long does it take before it's effective". Having some docs to point to would be nice. >> How long before all the mapped user IDs are converted to the new >> domain? (I think I know the answer, but what should the man >> page say about it). > The keys all have timeouts on them... so when they timeout... > I guess maybe the key chain can be invalidate when a > change is noticed? That would be easy with a daemon not > so easy with a command. > >> >> For instance, the kernel's cache of keys delays the effect of >> changing the result of that TXT query. Should the man page >> recommend a flush of that cache on clients? > Hmm... adding a second step.. it probably should be automatic. That would be nice, but seems like it would be difficult when using TXT, unless the host stored the previous query result somewhere so it could be compared with the latest one. -- Chuck Lever -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On 08/15/2016 11:16 AM, Chuck Lever wrote: >>>> On Aug 11, 2016, at 5:26 PM, Steve Dickson <SteveD@redhat.com> wrote: >>>> >>> >>>> >>> In domain_from_dns(), when at the hostname is a FQHN >>>> >>> query the DNS server for the _nfsv4idmapdomain TXT >>>> >>> record. If the record exists, use that as the >>>> >>> NFSv4 domain. >>>> >>> >>>> >>> Note, this query will only happen if the domain name >>>> >>> is not set in the /etc/idmapd.conf >>> >> >>> >> Is there a man page update that goes with this? The order in >>> >> which the library searches for the domain name should be >>> >> documented. idmapd.conf(5), maybe. >> > Yes... I should have made this an RFC patch since I just >> > wanted to get core out there for for comments... >> > The man page needs to updated as well as the configure.ac. > To enable this feature IMO a better choice is to use a command > line option on nfsidmap and rpc.idmapd. I've be thinking about this... I don't think a command line option is possible... How does a command line option tell a internal library routine what to do? w/out creating new interface which is something I don't think we want to do... steved. -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Hey bud- > On Aug 18, 2016, at 12:40 PM, Steve Dickson <SteveD@redhat.com> wrote: > > > > On 08/15/2016 11:16 AM, Chuck Lever wrote: >>>>> On Aug 11, 2016, at 5:26 PM, Steve Dickson <SteveD@redhat.com> wrote: >>>>>>>> >>>>>>>> In domain_from_dns(), when at the hostname is a FQHN >>>>>>>> query the DNS server for the _nfsv4idmapdomain TXT >>>>>>>> record. If the record exists, use that as the >>>>>>>> NFSv4 domain. >>>>>>>> >>>>>>>> Note, this query will only happen if the domain name >>>>>>>> is not set in the /etc/idmapd.conf >>>>>> >>>>>> Is there a man page update that goes with this? The order in >>>>>> which the library searches for the domain name should be >>>>>> documented. idmapd.conf(5), maybe. >>>> Yes... I should have made this an RFC patch since I just >>>> wanted to get core out there for for comments... >>>> The man page needs to updated as well as the configure.ac. >> To enable this feature IMO a better choice is to use a command >> line option on nfsidmap and rpc.idmapd. > I've be thinking about this... I don't think a command line > option is possible... How does a command line option tell a > internal library routine what to do? w/out creating new interface > which is something I don't think we want to do... I may have mentioned this elsewhere, but I changed my mind about this already: There's probably no need to have a command line option or a build-time setting here, because setting the Domain = variable in /etc/idmapd.conf is enough to disable the new query. -- Chuck Lever -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/libnfsidmap.c b/libnfsidmap.c index 2db4d13..7b8c0ed 100644 --- a/libnfsidmap.c +++ b/libnfsidmap.c @@ -53,6 +53,10 @@ #include <stdarg.h> #include <dlfcn.h> #include <ctype.h> +#include <resolv.h> +#include <arpa/nameser.h> +#include <arpa/nameser_compat.h> + #include "nfsidmap.h" #include "nfsidmap_internal.h" #include "cfg.h" @@ -79,6 +83,11 @@ gid_t nobody_gid = (gid_t)-1; #define IDMAPD_DEFAULT_DOMAIN "localdomain" #endif +#ifndef NFS4DNSTXTREC +#define NFS4DNSTXTREC "_nfsv4idmapdomain" +#endif + + /* Default logging fuction */ static void default_logger(const char *fmt, ...) { @@ -114,6 +123,93 @@ static int id_as_chars(char *name, uid_t *id) return 1; } +static int dns_txt_query(char *domain, char **nfs4domain) +{ + char *txtname = NFS4DNSTXTREC; + char *msg, *answ, *eom, *mptr; + int len, status = -1; + HEADER *hdr; + + msg = calloc(1, NS_MAXMSG); + if (msg == NULL) + return -1; + + answ = calloc(1, NS_MAXMSG); + if (answ == NULL) { + free(msg); + return -1; + } + + if (res_init() < 0) { + IDMAP_LOG(2, ("libnfsidmap: res_init() failed for %s.%s: %s\n", + txtname, domain, hstrerror(h_errno))); + goto freemem; + } + len = res_querydomain(txtname, domain, C_IN, T_TXT, msg, NS_MAXMSG); + if (len < 0) { + IDMAP_LOG(2, ("libnfsidmap: res_querydomain() failed for %s.%s: %s\n", + txtname, domain, hstrerror(h_errno))); + goto freemem; + } + hdr = (HEADER *)msg; + + /* See if there is an answer */ + if (ntohs(hdr->ancount) < 1) { + IDMAP_LOG(2, ("libnfsidmap: No TXT record for %s.%s\n", + txtname, domain)); + goto freemem; + } + /* find the EndOfMessage */ + eom = msg + len; + + /* skip header */ + mptr = &msg[HFIXEDSZ]; + + /* skip name field in question section */ + mptr += dn_skipname(mptr, eom) + QFIXEDSZ; + + /* read in the question */ + len = dn_expand(msg, eom, mptr, answ, NS_MAXDNAME); + if (len < 0) { /* does this really matter?? */ + IDMAP_LOG(2, ("libnfsidmap: No question section for %s.%s: %s\n", + txtname, domain, hstrerror(h_errno))); + goto freemem; + } + + /* + * Now, dissect the answer section, Note: if there + * are more than one answer only the first + * one will be used. + */ + + /* skip passed the name field */ + mptr += dn_skipname(mptr, eom); + /* skip pass the type class and ttl fields */ + mptr += 2 + 2 + 4; + + /* make sure there is some data */ + GETSHORT(len, mptr); + if (len < 0) { + IDMAP_LOG(2, ("libnfsidmap: No data in answer for %s.%s\n", + txtname, domain)); + goto freemem; + } + /* get the lenght field */ + len = (int)*mptr++; + /* copy the data */ + memcpy(answ, mptr, len); + answ[len] = '\0'; + + *nfs4domain = strdup(answ); + status = 0; + +freemem: + free(msg); + free(answ); + + return (status); +} + static int domain_from_dns(char **domain) { struct hostent *he; @@ -125,7 +221,13 @@ static int domain_from_dns(char **domain) return -1; if ((c = strchr(he->h_name, '.')) == NULL || *++c == '\0') return -1; - *domain = strdup(c); + /* + * Query DNS to see if the _nfsv4idmapdomain TXT record exists + * If so use it... + */ + if (dns_txt_query(c, domain) < 0) + *domain = strdup(c); + return 0; }
In domain_from_dns(), when at the hostname is a FQHN query the DNS server for the _nfsv4idmapdomain TXT record. If the record exists, use that as the NFSv4 domain. Note, this query will only happen if the domain name is not set in the /etc/idmapd.conf Signed-off-by: Steve Dickson <steved@redhat.com> --- libnfsidmap.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 103 insertions(+), 1 deletion(-)