Message ID | 1303914990-7804-1-git-send-email-shirishpargaonkar@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Wed, 27 Apr 2011 09:36:30 -0500 shirishpargaonkar@gmail.com wrote: > From: Shirish Pargaonkar <shirishpargaonkar@gmail.com> > > Handle cifs_idmap type of key. Extract a SID string from the description > and map it to either an uid or gid using winbind APIs. > If that fails (e.g. because winbind is not installed/running or winbind returns > an error), try to obtain uid of 'nobody' and gid of 'nogroup'. > And if that fails, kernel assigns uid and gid (from mount superblock). > > Enable including winbind header files and idmapping code conditional > to winbind devel rpms (header and library). > > An entry such as this > > create cifs.cifs_idmap * * /usr/sbin/cifs.upcall %k > > is needed in the file /etc/request-key.conf. > > > Signed-off-by: Shirish Pargaonkar <shirishpargaonkar@gmail.com> > --- > Makefile.am | 2 +- > cifs.upcall.c | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- > configure.ac | 35 +++++++++++++++++ > 3 files changed, 152 insertions(+), 2 deletions(-) > > diff --git a/Makefile.am b/Makefile.am > index 67a0190..13b6c16 100644 > --- a/Makefile.am > +++ b/Makefile.am > @@ -11,7 +11,7 @@ man_MANS = mount.cifs.8 > if CONFIG_CIFSUPCALL > sbin_PROGRAMS = cifs.upcall > cifs_upcall_SOURCES = cifs.upcall.c data_blob.c asn1.c spnego.c util.c > -cifs_upcall_LDADD = -ltalloc -lkeyutils $(KRB5_LDADD) > +cifs_upcall_LDADD = -ltalloc -lkeyutils $(KRB5_LDADD) $(WINB_LDADD) > man_MANS += cifs.upcall.8 > > # > diff --git a/cifs.upcall.c b/cifs.upcall.c > index 479517c..6c2088b 100644 > --- a/cifs.upcall.c > +++ b/cifs.upcall.c > @@ -45,6 +45,15 @@ > #include <time.h> > #include <netdb.h> > #include <arpa/inet.h> > +#include <stdint.h> > +#include <stdbool.h> > +#include <stdio.h> > +#include <stdlib.h> > +#include <errno.h> > +#include <limits.h> > +#ifdef HAVE_WBCLIENT_H > +#include <wbclient.h> > +#endif /* HAVE_WBCLIENT_H */ > > #include "util.h" > #include "replace.h" > @@ -653,7 +662,7 @@ static int cifs_resolver(const key_serial_t key, const char *key_descr) > const char *keyend = key_descr; > /* skip next 4 ';' delimiters to get to description */ > for (c = 1; c <= 4; c++) { > - keyend = index(keyend + 1, ';'); > + keyend = rindex(keyend + 1, ';'); > if (!keyend) { > syslog(LOG_ERR, "invalid key description: %s", > key_descr); > @@ -695,6 +704,105 @@ static int cifs_resolver(const key_serial_t key, const char *key_descr) > return 0; > } > > +#ifdef HAVE_LIBWBCLIENT > +static int > +cifs_sid_resolver(const key_serial_t key, const char *key_descr) > +{ > + int i; > + uid_t uid = 0; > + gid_t gid = 0;; > + wbcErr rc = 1; > + const char *keyend = key_descr; > + struct wbcDomainSid sid; > + struct passwd *pw; > + struct group *gr; > + > + /* skip next 4 ';' delimiters to get to description */ > + for (i = 1; i <= 4; ++i) { > + keyend = index(keyend + 1, ';'); > + if (!keyend) { > + syslog(LOG_ERR, "invalid key description: %s", > + key_descr); > + return 1; > + } > + } > + keyend++; > + > + /* > + * Use winbind to convert received string to a SID and lookup > + * name and map that SID to an uid. If either of these > + * function calls return with an error, use system calls to obtain > + * uid of user "nobody". If winbind fails to map a SID to an UID > + * and there is no user named "nobody", return error to the > + * upcall caller. Otherwise instanticate a key using that uid. > + * > + * The same applies to SID and gid mapping. Instead of a > + * user "nobody", user "nogroup" is looked up if winbind > + * fails to map a SID to a gid. > + */ > + if (strncmp(keyend, "os", 2) == 0) { > + keyend = index(keyend + 1, ':'); > + keyend++; > + rc = wbcStringToSid(keyend, &sid); > + if (rc) > + syslog(LOG_DEBUG, "O strtosid: %s, rc: %d", keyend, rc); > + else { > + rc = wbcSidToUid(&sid, &uid); > + if (rc) > + syslog(LOG_DEBUG, "SID %s to uid wbc error: %d", > + keyend, rc); > + } > + if (rc) { /* either of the two wbcSid functions failed */ > + pw = getpwnam("nobody"); > + if (!pw) > + syslog(LOG_DEBUG, "SID %s to uid pw error: %d", > + keyend, rc); > + else { > + uid = pw->pw_uid; > + rc = 0; > + } > + } > + if (!rc) { /* SID has been mapped to a uid */ > + rc = keyctl_instantiate(key, &uid, sizeof(uid_t), 0); > + if (rc) > + syslog(LOG_ERR, "%s: key inst: %s", > + __func__, strerror(errno)); > + } > + } else if (strncmp(keyend, "gs", 2) == 0) { > + keyend = index(keyend + 1, ':'); > + keyend++; > + rc = wbcStringToSid(keyend, &sid); > + if (rc) > + syslog(LOG_DEBUG, "O strtosid: %s, rc: %d", keyend, rc); > + else { > + rc = wbcSidToGid(&sid, &gid); > + if (rc) > + syslog(LOG_DEBUG, "SID %s to gid wbc error: %d", > + keyend, rc); > + } > + if (rc) { /* either of the two wbcSid functions failed */ > + gr = getgrnam("nogroup"); > + if (!gr) > + syslog(LOG_DEBUG, "SID %s to gid pw error: %d", > + keyend, rc); > + else { > + gid = gr->gr_gid; > + rc = 0; > + } > + } > + if (!rc) { /* SID has been mapped to a gid */ > + rc = keyctl_instantiate(key, &gid, sizeof(gid_t), 0); > + if (rc) > + syslog(LOG_ERR, "%s: key inst: %s", > + __func__, strerror(errno)); > + } > + } else > + syslog(LOG_DEBUG, "Invalid SID: %s", keyend); > + > + return rc; > +} > +#endif /* HAVE_LIBWBCLIENT */ > + > /* > * Older kernels sent IPv6 addresses without colons. Well, at least > * they're fixed-length strings. Convert these addresses to have colon > @@ -832,6 +940,13 @@ int main(const int argc, char *const argv[]) > rc = cifs_resolver(key, buf); > goto out; > } > +#ifdef HAVE_LIBWBCLIENT > + if ((strncmp(buf, "cifs.cifs_idmap", sizeof("cifs.cifs_idmap") - 1) > + == 0)) { > + rc = cifs_sid_resolver(key, buf); > + goto out; > + } > +#endif /* HAVE_LIBWBCLIENT */ > > have = decode_key_description(buf, &arg); > SAFE_FREE(buf); > diff --git a/configure.ac b/configure.ac > index e0e2a60..45800bd 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -89,6 +89,41 @@ if test $enable_cifsupcall != "no"; then > AC_SUBST(KRB5_LDADD) > fi > > +if test $enable_cifsupcall != "no"; then > + AC_CHECK_LIB([wbclient], [wbcStringToSid], > + [ WINB_LDADD='-lwbclient' ] [ AC_DEFINE(HAVE_LIBWBCLIENT, 1, ["define a var"]) ], AC_MSG_ERROR([no functioning wbclient library found!])) > + AC_SUBST(WINB_LDADD) > +fi > + > +if test $enable_cifsupcall != "no"; then > + AC_CHECK_HEADERS([stdbool.h]) > + AC_CHECK_HEADERS([stdio.h]) > + AC_CHECK_HEADERS([errno.h]) > + AC_CHECK_HEADERS([wbclient.h], , [AC_MSG_ERROR([wbclient.h not found, consider installing libwbclient-devel.])], > +[#ifdef HAVE_STDINT_H > +#include <stdint.h> > +#endif > +] > +[#ifdef HAVE_STDBOOL_H > +#include <stdbool.h> > +#endif > +] > +[#ifdef HAVE_STDIO_H > +#include <stdio.h> > +#endif > +] > +[#ifdef HAVE_STDLIB_H > +#include <stdlib.h> > +#endif > +] > +[#ifdef HAVE_ERRNO_H > +#include <errno.h> > +#endif > +] > +) > +fi What on earth is the stuff above? configure.ac is at it's heart a shell script, so I'm pretty sure the above will end up looking like a bunch of comments wrapped in square brackets. > + > +# Checks for typedefs, structures, and compiler characteristics. > if test $enable_cifscreds = "yes"; then > AC_CHECK_HEADERS([keyutils.h], , [AC_MSG_ERROR([keyutils.h not found, consider installing keyutils-libs-devel.])]) > fi I think this code should be a separate program. I realize that we have precedent for making this part of the same binary since the SPNEGO and DNS upcalls are that way, but I don't think that was a good choice in retrospect. These programs ought to be small and single-purpose. If you add this in, then every time you do a SPENGO upcall, you'll get the wb_client libs linked in. Vice versa for the idmapping upcall wrt to krb5 libs (which is really a bigger problem). So, keeping them as part of the same program has clear drawbacks. It also makes the code more messy. The DNS part of this program should (eventually) go away now that it's part of a unified kernel infrastructure. At that point cifs.upcall will be a SPNEGO upcall only again. Let's foster that by making this a separate program in its own right. With that change too, I'd like to see a --enable-cifsidmap option or something that allows the new program to be conditionally compiled. That can default to "on" but should autodisable when libwbclient or other needed libs aren't present.
On Mon, May 2, 2011 at 6:51 AM, Jeff Layton <jlayton@redhat.com> wrote: > On Wed, 27 Apr 2011 09:36:30 -0500 > shirishpargaonkar@gmail.com wrote: > >> From: Shirish Pargaonkar <shirishpargaonkar@gmail.com> >> >> Handle cifs_idmap type of key. Extract a SID string from the description >> and map it to either an uid or gid using winbind APIs. >> If that fails (e.g. because winbind is not installed/running or winbind returns >> an error), try to obtain uid of 'nobody' and gid of 'nogroup'. >> And if that fails, kernel assigns uid and gid (from mount superblock). >> >> Enable including winbind header files and idmapping code conditional >> to winbind devel rpms (header and library). >> >> An entry such as this >> >> create cifs.cifs_idmap * * /usr/sbin/cifs.upcall %k >> >> is needed in the file /etc/request-key.conf. >> >> >> Signed-off-by: Shirish Pargaonkar <shirishpargaonkar@gmail.com> >> --- >> Makefile.am | 2 +- >> cifs.upcall.c | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- >> configure.ac | 35 +++++++++++++++++ >> 3 files changed, 152 insertions(+), 2 deletions(-) >> >> diff --git a/Makefile.am b/Makefile.am >> index 67a0190..13b6c16 100644 >> --- a/Makefile.am >> +++ b/Makefile.am >> @@ -11,7 +11,7 @@ man_MANS = mount.cifs.8 >> if CONFIG_CIFSUPCALL >> sbin_PROGRAMS = cifs.upcall >> cifs_upcall_SOURCES = cifs.upcall.c data_blob.c asn1.c spnego.c util.c >> -cifs_upcall_LDADD = -ltalloc -lkeyutils $(KRB5_LDADD) >> +cifs_upcall_LDADD = -ltalloc -lkeyutils $(KRB5_LDADD) $(WINB_LDADD) >> man_MANS += cifs.upcall.8 >> >> # >> diff --git a/cifs.upcall.c b/cifs.upcall.c >> index 479517c..6c2088b 100644 >> --- a/cifs.upcall.c >> +++ b/cifs.upcall.c >> @@ -45,6 +45,15 @@ >> #include <time.h> >> #include <netdb.h> >> #include <arpa/inet.h> >> +#include <stdint.h> >> +#include <stdbool.h> >> +#include <stdio.h> >> +#include <stdlib.h> >> +#include <errno.h> >> +#include <limits.h> >> +#ifdef HAVE_WBCLIENT_H >> +#include <wbclient.h> >> +#endif /* HAVE_WBCLIENT_H */ >> >> #include "util.h" >> #include "replace.h" >> @@ -653,7 +662,7 @@ static int cifs_resolver(const key_serial_t key, const char *key_descr) >> const char *keyend = key_descr; >> /* skip next 4 ';' delimiters to get to description */ >> for (c = 1; c <= 4; c++) { >> - keyend = index(keyend + 1, ';'); >> + keyend = rindex(keyend + 1, ';'); >> if (!keyend) { >> syslog(LOG_ERR, "invalid key description: %s", >> key_descr); >> @@ -695,6 +704,105 @@ static int cifs_resolver(const key_serial_t key, const char *key_descr) >> return 0; >> } >> >> +#ifdef HAVE_LIBWBCLIENT >> +static int >> +cifs_sid_resolver(const key_serial_t key, const char *key_descr) >> +{ >> + int i; >> + uid_t uid = 0; >> + gid_t gid = 0;; >> + wbcErr rc = 1; >> + const char *keyend = key_descr; >> + struct wbcDomainSid sid; >> + struct passwd *pw; >> + struct group *gr; >> + >> + /* skip next 4 ';' delimiters to get to description */ >> + for (i = 1; i <= 4; ++i) { >> + keyend = index(keyend + 1, ';'); >> + if (!keyend) { >> + syslog(LOG_ERR, "invalid key description: %s", >> + key_descr); >> + return 1; >> + } >> + } >> + keyend++; >> + >> + /* >> + * Use winbind to convert received string to a SID and lookup >> + * name and map that SID to an uid. If either of these >> + * function calls return with an error, use system calls to obtain >> + * uid of user "nobody". If winbind fails to map a SID to an UID >> + * and there is no user named "nobody", return error to the >> + * upcall caller. Otherwise instanticate a key using that uid. >> + * >> + * The same applies to SID and gid mapping. Instead of a >> + * user "nobody", user "nogroup" is looked up if winbind >> + * fails to map a SID to a gid. >> + */ >> + if (strncmp(keyend, "os", 2) == 0) { >> + keyend = index(keyend + 1, ':'); >> + keyend++; >> + rc = wbcStringToSid(keyend, &sid); >> + if (rc) >> + syslog(LOG_DEBUG, "O strtosid: %s, rc: %d", keyend, rc); >> + else { >> + rc = wbcSidToUid(&sid, &uid); >> + if (rc) >> + syslog(LOG_DEBUG, "SID %s to uid wbc error: %d", >> + keyend, rc); >> + } >> + if (rc) { /* either of the two wbcSid functions failed */ >> + pw = getpwnam("nobody"); >> + if (!pw) >> + syslog(LOG_DEBUG, "SID %s to uid pw error: %d", >> + keyend, rc); >> + else { >> + uid = pw->pw_uid; >> + rc = 0; >> + } >> + } >> + if (!rc) { /* SID has been mapped to a uid */ >> + rc = keyctl_instantiate(key, &uid, sizeof(uid_t), 0); >> + if (rc) >> + syslog(LOG_ERR, "%s: key inst: %s", >> + __func__, strerror(errno)); >> + } >> + } else if (strncmp(keyend, "gs", 2) == 0) { >> + keyend = index(keyend + 1, ':'); >> + keyend++; >> + rc = wbcStringToSid(keyend, &sid); >> + if (rc) >> + syslog(LOG_DEBUG, "O strtosid: %s, rc: %d", keyend, rc); >> + else { >> + rc = wbcSidToGid(&sid, &gid); >> + if (rc) >> + syslog(LOG_DEBUG, "SID %s to gid wbc error: %d", >> + keyend, rc); >> + } >> + if (rc) { /* either of the two wbcSid functions failed */ >> + gr = getgrnam("nogroup"); >> + if (!gr) >> + syslog(LOG_DEBUG, "SID %s to gid pw error: %d", >> + keyend, rc); >> + else { >> + gid = gr->gr_gid; >> + rc = 0; >> + } >> + } >> + if (!rc) { /* SID has been mapped to a gid */ >> + rc = keyctl_instantiate(key, &gid, sizeof(gid_t), 0); >> + if (rc) >> + syslog(LOG_ERR, "%s: key inst: %s", >> + __func__, strerror(errno)); >> + } >> + } else >> + syslog(LOG_DEBUG, "Invalid SID: %s", keyend); >> + >> + return rc; >> +} >> +#endif /* HAVE_LIBWBCLIENT */ >> + >> /* >> * Older kernels sent IPv6 addresses without colons. Well, at least >> * they're fixed-length strings. Convert these addresses to have colon >> @@ -832,6 +940,13 @@ int main(const int argc, char *const argv[]) >> rc = cifs_resolver(key, buf); >> goto out; >> } >> +#ifdef HAVE_LIBWBCLIENT >> + if ((strncmp(buf, "cifs.cifs_idmap", sizeof("cifs.cifs_idmap") - 1) >> + == 0)) { >> + rc = cifs_sid_resolver(key, buf); >> + goto out; >> + } >> +#endif /* HAVE_LIBWBCLIENT */ >> >> have = decode_key_description(buf, &arg); >> SAFE_FREE(buf); >> diff --git a/configure.ac b/configure.ac >> index e0e2a60..45800bd 100644 >> --- a/configure.ac >> +++ b/configure.ac >> @@ -89,6 +89,41 @@ if test $enable_cifsupcall != "no"; then >> AC_SUBST(KRB5_LDADD) >> fi >> >> +if test $enable_cifsupcall != "no"; then >> + AC_CHECK_LIB([wbclient], [wbcStringToSid], >> + [ WINB_LDADD='-lwbclient' ] [ AC_DEFINE(HAVE_LIBWBCLIENT, 1, ["define a var"]) ], AC_MSG_ERROR([no functioning wbclient library found!])) >> + AC_SUBST(WINB_LDADD) >> +fi >> + >> +if test $enable_cifsupcall != "no"; then >> + AC_CHECK_HEADERS([stdbool.h]) >> + AC_CHECK_HEADERS([stdio.h]) >> + AC_CHECK_HEADERS([errno.h]) >> + AC_CHECK_HEADERS([wbclient.h], , [AC_MSG_ERROR([wbclient.h not found, consider installing libwbclient-devel.])], >> +[#ifdef HAVE_STDINT_H >> +#include <stdint.h> >> +#endif >> +] >> +[#ifdef HAVE_STDBOOL_H >> +#include <stdbool.h> >> +#endif >> +] >> +[#ifdef HAVE_STDIO_H >> +#include <stdio.h> >> +#endif >> +] >> +[#ifdef HAVE_STDLIB_H >> +#include <stdlib.h> >> +#endif >> +] >> +[#ifdef HAVE_ERRNO_H >> +#include <errno.h> >> +#endif >> +] >> +) >> +fi > > What on earth is the stuff above? configure.ac is at it's heart a shell > script, so I'm pretty sure the above will end up looking like a bunch > of comments wrapped in square brackets. > Without it, I see following in config.log checking wbclient.h usability... no checking wbclient.h presence... yes configure: WARNING: wbclient.h: present but cannot be compiled configure: WARNING: wbclient.h: check for missing prerequisite headers? configure: WARNING: wbclient.h: see the Autoconf documentation configure: WARNING: wbclient.h: section "Present But Cannot Be Compiled" configure: WARNING: wbclient.h: proceeding with the preprocessor's result configure: WARNING: wbclient.h: in the future, the compiler will take precedence configure: WARNING: ## ----------------------------------- ## configure: WARNING: ## Report this to cifs-utils@samba.org ## configure: WARNING: ## ----------------------------------- ## checking for wbclient.h... yes With it, this checking for wbcStringToSid in -lwbclient... yes checking stdbool.h usability... yes checking stdbool.h presence... yes checking for stdbool.h... yes checking stdio.h usability... yes checking stdio.h presence... yes checking for stdio.h... yes checking errno.h usability... yes checking errno.h presence... yes checking for errno.h... yes checking for wbclient.h... yes >> + >> +# Checks for typedefs, structures, and compiler characteristics. >> if test $enable_cifscreds = "yes"; then >> AC_CHECK_HEADERS([keyutils.h], , [AC_MSG_ERROR([keyutils.h not found, consider installing keyutils-libs-devel.])]) >> fi > > > > I think this code should be a separate program. I realize that we have > precedent for making this part of the same binary since the SPNEGO and > DNS upcalls are that way, but I don't think that was a good choice in > retrospect. > > These programs ought to be small and single-purpose. If you add this > in, then every time you do a SPENGO upcall, you'll get the wb_client > libs linked in. Vice versa for the idmapping upcall wrt to krb5 libs > (which is really a bigger problem). So, keeping them as part of the > same program has clear drawbacks. It also makes the code more messy. > > The DNS part of this program should (eventually) go away now that it's > part of a unified kernel infrastructure. At that point cifs.upcall will > be a SPNEGO upcall only again. Let's foster that by making this a > separate program in its own right. > > With that change too, I'd like to see a --enable-cifsidmap option or > something that allows the new program to be conditionally compiled. > That can default to "on" but should autodisable when libwbclient or > other needed libs aren't present. > > -- > Jeff Layton <jlayton@redhat.com> > -- To unsubscribe from this list: send the line "unsubscribe linux-cifs" 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/Makefile.am b/Makefile.am index 67a0190..13b6c16 100644 --- a/Makefile.am +++ b/Makefile.am @@ -11,7 +11,7 @@ man_MANS = mount.cifs.8 if CONFIG_CIFSUPCALL sbin_PROGRAMS = cifs.upcall cifs_upcall_SOURCES = cifs.upcall.c data_blob.c asn1.c spnego.c util.c -cifs_upcall_LDADD = -ltalloc -lkeyutils $(KRB5_LDADD) +cifs_upcall_LDADD = -ltalloc -lkeyutils $(KRB5_LDADD) $(WINB_LDADD) man_MANS += cifs.upcall.8 # diff --git a/cifs.upcall.c b/cifs.upcall.c index 479517c..6c2088b 100644 --- a/cifs.upcall.c +++ b/cifs.upcall.c @@ -45,6 +45,15 @@ #include <time.h> #include <netdb.h> #include <arpa/inet.h> +#include <stdint.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <limits.h> +#ifdef HAVE_WBCLIENT_H +#include <wbclient.h> +#endif /* HAVE_WBCLIENT_H */ #include "util.h" #include "replace.h" @@ -653,7 +662,7 @@ static int cifs_resolver(const key_serial_t key, const char *key_descr) const char *keyend = key_descr; /* skip next 4 ';' delimiters to get to description */ for (c = 1; c <= 4; c++) { - keyend = index(keyend + 1, ';'); + keyend = rindex(keyend + 1, ';'); if (!keyend) { syslog(LOG_ERR, "invalid key description: %s", key_descr); @@ -695,6 +704,105 @@ static int cifs_resolver(const key_serial_t key, const char *key_descr) return 0; } +#ifdef HAVE_LIBWBCLIENT +static int +cifs_sid_resolver(const key_serial_t key, const char *key_descr) +{ + int i; + uid_t uid = 0; + gid_t gid = 0;; + wbcErr rc = 1; + const char *keyend = key_descr; + struct wbcDomainSid sid; + struct passwd *pw; + struct group *gr; + + /* skip next 4 ';' delimiters to get to description */ + for (i = 1; i <= 4; ++i) { + keyend = index(keyend + 1, ';'); + if (!keyend) { + syslog(LOG_ERR, "invalid key description: %s", + key_descr); + return 1; + } + } + keyend++; + + /* + * Use winbind to convert received string to a SID and lookup + * name and map that SID to an uid. If either of these + * function calls return with an error, use system calls to obtain + * uid of user "nobody". If winbind fails to map a SID to an UID + * and there is no user named "nobody", return error to the + * upcall caller. Otherwise instanticate a key using that uid. + * + * The same applies to SID and gid mapping. Instead of a + * user "nobody", user "nogroup" is looked up if winbind + * fails to map a SID to a gid. + */ + if (strncmp(keyend, "os", 2) == 0) { + keyend = index(keyend + 1, ':'); + keyend++; + rc = wbcStringToSid(keyend, &sid); + if (rc) + syslog(LOG_DEBUG, "O strtosid: %s, rc: %d", keyend, rc); + else { + rc = wbcSidToUid(&sid, &uid); + if (rc) + syslog(LOG_DEBUG, "SID %s to uid wbc error: %d", + keyend, rc); + } + if (rc) { /* either of the two wbcSid functions failed */ + pw = getpwnam("nobody"); + if (!pw) + syslog(LOG_DEBUG, "SID %s to uid pw error: %d", + keyend, rc); + else { + uid = pw->pw_uid; + rc = 0; + } + } + if (!rc) { /* SID has been mapped to a uid */ + rc = keyctl_instantiate(key, &uid, sizeof(uid_t), 0); + if (rc) + syslog(LOG_ERR, "%s: key inst: %s", + __func__, strerror(errno)); + } + } else if (strncmp(keyend, "gs", 2) == 0) { + keyend = index(keyend + 1, ':'); + keyend++; + rc = wbcStringToSid(keyend, &sid); + if (rc) + syslog(LOG_DEBUG, "O strtosid: %s, rc: %d", keyend, rc); + else { + rc = wbcSidToGid(&sid, &gid); + if (rc) + syslog(LOG_DEBUG, "SID %s to gid wbc error: %d", + keyend, rc); + } + if (rc) { /* either of the two wbcSid functions failed */ + gr = getgrnam("nogroup"); + if (!gr) + syslog(LOG_DEBUG, "SID %s to gid pw error: %d", + keyend, rc); + else { + gid = gr->gr_gid; + rc = 0; + } + } + if (!rc) { /* SID has been mapped to a gid */ + rc = keyctl_instantiate(key, &gid, sizeof(gid_t), 0); + if (rc) + syslog(LOG_ERR, "%s: key inst: %s", + __func__, strerror(errno)); + } + } else + syslog(LOG_DEBUG, "Invalid SID: %s", keyend); + + return rc; +} +#endif /* HAVE_LIBWBCLIENT */ + /* * Older kernels sent IPv6 addresses without colons. Well, at least * they're fixed-length strings. Convert these addresses to have colon @@ -832,6 +940,13 @@ int main(const int argc, char *const argv[]) rc = cifs_resolver(key, buf); goto out; } +#ifdef HAVE_LIBWBCLIENT + if ((strncmp(buf, "cifs.cifs_idmap", sizeof("cifs.cifs_idmap") - 1) + == 0)) { + rc = cifs_sid_resolver(key, buf); + goto out; + } +#endif /* HAVE_LIBWBCLIENT */ have = decode_key_description(buf, &arg); SAFE_FREE(buf); diff --git a/configure.ac b/configure.ac index e0e2a60..45800bd 100644 --- a/configure.ac +++ b/configure.ac @@ -89,6 +89,41 @@ if test $enable_cifsupcall != "no"; then AC_SUBST(KRB5_LDADD) fi +if test $enable_cifsupcall != "no"; then + AC_CHECK_LIB([wbclient], [wbcStringToSid], + [ WINB_LDADD='-lwbclient' ] [ AC_DEFINE(HAVE_LIBWBCLIENT, 1, ["define a var"]) ], AC_MSG_ERROR([no functioning wbclient library found!])) + AC_SUBST(WINB_LDADD) +fi + +if test $enable_cifsupcall != "no"; then + AC_CHECK_HEADERS([stdbool.h]) + AC_CHECK_HEADERS([stdio.h]) + AC_CHECK_HEADERS([errno.h]) + AC_CHECK_HEADERS([wbclient.h], , [AC_MSG_ERROR([wbclient.h not found, consider installing libwbclient-devel.])], +[#ifdef HAVE_STDINT_H +#include <stdint.h> +#endif +] +[#ifdef HAVE_STDBOOL_H +#include <stdbool.h> +#endif +] +[#ifdef HAVE_STDIO_H +#include <stdio.h> +#endif +] +[#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif +] +[#ifdef HAVE_ERRNO_H +#include <errno.h> +#endif +] +) +fi + +# Checks for typedefs, structures, and compiler characteristics. if test $enable_cifscreds = "yes"; then AC_CHECK_HEADERS([keyutils.h], , [AC_MSG_ERROR([keyutils.h not found, consider installing keyutils-libs-devel.])]) fi