Whamcloud - gitweb
LU-16630 sec: improve Kerberos cross-realm trust remapping 59/50259/6
authorSebastien Buisson <sbuisson@ddn.com>
Fri, 10 Mar 2023 17:02:31 +0000 (18:02 +0100)
committerOleg Drokin <green@whamcloud.com>
Tue, 11 Apr 2023 21:56:56 +0000 (21:56 +0000)
Improve Kerberos cross-realm trust remapping by leveraging existing
Kerberos mechanisms. gss_localname() can be used to resolve usernames:
it goes through the auth_to_local translation rules in krb5.conf and
thus can easily be configured by security administrators.
This new mechanism does not replace the existing and rudimentary
mapping based on /etc/lustre/idmap.conf. If /etc/lustre/idmap.conf
exists, it is used for user mapping. If not, the new mechanism based
on gss_localname() gets involved.
But we now print a warning that idmap.conf is deprecated if we detect
it is in use.

Signed-off-by: Sebastien Buisson <sbuisson@ddn.com>
Change-Id: Iaaf15a757dc246673e2f412181219cc978079fab
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/50259
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Aurelien Degremont <adegremont@nvidia.com>
Reviewed-by: Jonathan Calmels <jcalmels@nvidia.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/utils/gss/err_util.h
lustre/utils/gss/lgss_utils.h
lustre/utils/gss/lsupport.c
lustre/utils/gss/lsupport.h
lustre/utils/gss/svcgssd.c
lustre/utils/gss/svcgssd.h
lustre/utils/gss/svcgssd_main_loop.c
lustre/utils/gss/svcgssd_proc.c

index 0070a3b..5957604 100644 (file)
 #ifndef _ERR_UTIL_H_
 #define _ERR_UTIL_H_
 
+/*
+ * log level:
+ * LL_ERR:      critical error messages
+ * LL_WARN:     warning (default)
+ * LL_INFO:     important infomation
+ * LL_DEBUG:    debugging
+ * LL_TRACE:    excessive tracing messages
+ */
+typedef enum {
+       LL_ERR          = 0,
+       LL_WARN         = 1,
+       LL_INFO         = 2,
+       LL_DEBUG        = 3,
+       LL_TRACE        = 4,
+       LL_MAX
+} loglevel_t;
+
 void initerr(char *progname, int verbosity, int fg);
 void printerr(int priority, char *format, ...)
              __attribute__((__format__(__printf__, 2, 3)));
index 98c25c9..607fb31 100644 (file)
@@ -45,6 +45,7 @@
 #include <gssapi/gssapi.h>
 
 #include "lsupport.h"
+#include "err_util.h"
 
 #define LGSS_SVC_MGS_STR        "lustre_mgs"
 #define LGSS_SVC_MDS_STR        "lustre_mds"
@@ -76,23 +77,6 @@ int lgss_mutex_unlock(lgss_mutex_id_t mid);
  * log facilities                       *
  ****************************************/
 
-/*
- * log level:
- * LL_ERR:      critical error messages
- * LL_WARN:     warning (default)
- * LL_INFO:     important infomation
- * LL_DEBUG:    debugging
- * LL_TRACE:    excessive tracing messages
- */
-typedef enum {
-        LL_ERR          = 0,
-        LL_WARN         = 1,
-        LL_INFO         = 2,
-        LL_DEBUG        = 3,
-        LL_TRACE        = 4,
-        LL_MAX
-} loglevel_t;
-
 extern loglevel_t g_log_level;
 
 void lgss_set_loglevel(loglevel_t level);
index 76a6034..343a6e6 100644 (file)
@@ -88,57 +88,58 @@ static struct __sem_s {
 
 void gssd_init_unique(int type)
 {
-        struct __sem_s *sem = &sems[type];
-        struct sembuf   sembuf;
+       struct __sem_s *sem = &sems[type];
+       struct sembuf   sembuf;
 
-        assert(type == GSSD_CLI || type == GSSD_SVC);
+       assert(type == GSSD_CLI || type == GSSD_SVC);
 
 again:
-        sem->sem_id = semget(sem->sem_key, 1, IPC_CREAT | IPC_EXCL | 0700);
-        if (sem->sem_id == -1) {
-                if (errno != EEXIST) {
-                        printerr(0, "Create sem: %s\n", strerror(errno));
-                        exit(-1);
-                }
-
-                /* already exist. Note there's still a small window racing
-                 * with other processes, due to the stupid semaphore semantics.
-                 */
-                sem->sem_id = semget(sem->sem_key, 0, 0700);
-                if (sem->sem_id == -1) {
-                        if (errno == ENOENT) {
-                                printerr(0, "another instance just exit, "
-                                         "try again\n");
-                                goto again;
-                        }
-
-                        printerr(0, "Obtain sem: %s\n", strerror(errno));
-                        exit(-1);
-                }
-        } else {
-                int val = 1;
-
-                if (semctl(sem->sem_id, 0, SETVAL, val) == -1) {
-                        printerr(0, "Initialize sem: %s\n",
-                                 strerror(errno));
-                        exit(-1);
-                }
-        }
-
-        sembuf.sem_num = 0;
-        sembuf.sem_op = -1;
-        sembuf.sem_flg = IPC_NOWAIT | SEM_UNDO;
-
-        if (semop(sem->sem_id, &sembuf, 1) != 0) {
-                if (errno == EAGAIN) {
-                        printerr(0, "Another instance is running, exit\n");
-                        exit(0);
-                }
-                printerr(0, "Grab sem: %s\n", strerror(errno));
-                exit(0);
-        }
-
-        printerr(2, "Successfully created %s global identity\n", sem->name);
+       sem->sem_id = semget(sem->sem_key, 1, IPC_CREAT | IPC_EXCL | 0700);
+       if (sem->sem_id == -1) {
+               if (errno != EEXIST) {
+                       printerr(LL_ERR, "Create sem: %s\n", strerror(errno));
+                       exit(-1);
+               }
+
+               /* already exist. Note there's still a small window racing
+                * with other processes, due to the stupid semaphore semantics.
+                */
+               sem->sem_id = semget(sem->sem_key, 0, 0700);
+               if (sem->sem_id == -1) {
+                       if (errno == ENOENT) {
+                               printerr(LL_ERR,
+                                        "another instance just exit, try again\n");
+                               goto again;
+                       }
+
+                       printerr(LL_ERR, "Obtain sem: %s\n", strerror(errno));
+                       exit(-1);
+               }
+       } else {
+               int val = 1;
+
+               if (semctl(sem->sem_id, 0, SETVAL, val) == -1) {
+                       printerr(LL_ERR, "Initialize sem: %s\n",
+                                strerror(errno));
+                       exit(-1);
+               }
+       }
+
+       sembuf.sem_num = 0;
+       sembuf.sem_op = -1;
+       sembuf.sem_flg = IPC_NOWAIT | SEM_UNDO;
+
+       if (semop(sem->sem_id, &sembuf, 1) != 0) {
+               if (errno == EAGAIN) {
+                       printerr(LL_ERR, "Another instance is running, exit\n");
+                       exit(0);
+               }
+               printerr(LL_ERR, "Grab sem: %s\n", strerror(errno));
+               exit(0);
+       }
+
+       printerr(LL_INFO, "Successfully created %s global identity\n",
+                sem->name);
 }
 
 void gssd_exit_unique(int type)
@@ -165,59 +166,59 @@ typedef int lnd_nid2hostname_t(char *lnd, uint32_t net, uint32_t addr,
 /* FIXME what about IPv6? */
 static
 int ipv4_nid2hostname(char *lnd, uint32_t net, uint32_t addr,
-                      char *buf, int buflen)
+                     char *buf, int buflen)
 {
-        struct hostent  *ent;
-
-        addr = htonl(addr);
-        ent = gethostbyaddr(&addr, sizeof(addr), AF_INET);
-        if (!ent) {
-                printerr(0, "%s: can't resolve 0x%x\n", lnd, addr);
-                return -1;
-        }
-        if (strlen(ent->h_name) >= buflen) {
-                printerr(0, "%s: name too long: %s\n", lnd, ent->h_name);
-                return -1;
-        }
-        strcpy(buf, ent->h_name);
-
-        printerr(2, "%s: net 0x%x, addr 0x%x => %s\n",
-                 lnd, net, addr, buf);
-        return 0;
+       struct hostent *ent;
+
+       addr = htonl(addr);
+       ent = gethostbyaddr(&addr, sizeof(addr), AF_INET);
+       if (!ent) {
+               printerr(LL_ERR, "%s: can't resolve 0x%x\n", lnd, addr);
+               return -1;
+       }
+       if (strlen(ent->h_name) >= buflen) {
+               printerr(LL_ERR, "%s: name too long: %s\n", lnd, ent->h_name);
+               return -1;
+       }
+       strcpy(buf, ent->h_name);
+
+       printerr(LL_INFO, "%s: net 0x%x, addr 0x%x => %s\n",
+                lnd, net, addr, buf);
+       return 0;
 }
 
 static
 int lolnd_nid2hostname(char *lnd, uint32_t net, uint32_t addr,
-                       char *buf, int buflen)
+                      char *buf, int buflen)
 {
-        struct utsname   uts;
-        struct hostent  *ent;
-
-        if (addr) {
-                printerr(0, "%s: addr is 0x%x, we expect 0\n", lnd, addr);
-                return -1;
-        }
-
-        if (uname(&uts)) {
-                printerr(0, "%s: failed obtain local machine name\n", lnd);
-                return -1;
-        }
-
-        ent = gethostbyname(uts.nodename);
-        if (!ent) {
-                printerr(0, "%s: failed obtain canonical name of %s\n",
-                         lnd, uts.nodename);
-                return -1;
-        }
-
-        if (strlen(ent->h_name) >= buflen) {
-                printerr(0, "%s: name too long: %s\n", lnd, ent->h_name);
-                return -1;
-        }
-        strcpy(buf, ent->h_name);
-
-        printerr(3, "%s: addr 0x%x => %s\n", lnd, addr, buf);
-        return 0;
+       struct utsname uts;
+       struct hostent *ent;
+
+       if (addr) {
+               printerr(LL_ERR, "%s: addr is 0x%x, we expect 0\n", lnd, addr);
+               return -1;
+       }
+
+       if (uname(&uts)) {
+               printerr(LL_ERR, "%s: failed obtain local machine name\n", lnd);
+               return -1;
+       }
+
+       ent = gethostbyname(uts.nodename);
+       if (!ent) {
+               printerr(LL_ERR, "%s: failed obtain canonical name of %s\n",
+                        lnd, uts.nodename);
+               return -1;
+       }
+
+       if (strlen(ent->h_name) >= buflen) {
+               printerr(LL_ERR, "%s: name too long: %s\n", lnd, ent->h_name);
+               return -1;
+       }
+       strcpy(buf, ent->h_name);
+
+       printerr(LL_DEBUG, "%s: addr 0x%x => %s\n", lnd, addr, buf);
+       return 0;
 }
 
 static int is_space(char c)
@@ -227,62 +228,64 @@ static int is_space(char c)
 
 static
 int external_nid2hostname(char *lnd, uint32_t net, uint32_t addr,
-                          char *namebuf, int namebuflen)
+                         char *namebuf, int namebuflen)
 {
-        const int bufsize = PATH_MAX + 256;
-        char buf[bufsize], *head, *tail;
-        FILE *fghn;
-
-        sprintf(buf, "%s %s 0x%x 0x%x", gethostname_ex, lnd, net, addr);
-        printerr(2, "cmd: %s\n", buf);
-
-        fghn = popen(buf, "r");
-        if (fghn == NULL) {
-                printerr(0, "failed to call %s\n", gethostname_ex);
-                return -1;
-        }
-
-        head = fgets(buf, bufsize, fghn);
-        if (head == NULL) {
-                printerr(0, "can't read from %s\n", gethostname_ex);
+       const int bufsize = PATH_MAX + 256;
+       char buf[bufsize], *head, *tail;
+       FILE *fghn;
+
+       sprintf(buf, "%s %s 0x%x 0x%x", gethostname_ex, lnd, net, addr);
+       printerr(LL_INFO, "cmd: %s\n", buf);
+
+       fghn = popen(buf, "r");
+       if (fghn == NULL) {
+               printerr(LL_ERR, "failed to call %s\n", gethostname_ex);
+               return -1;
+       }
+
+       head = fgets(buf, bufsize, fghn);
+       if (head == NULL) {
+               printerr(LL_ERR, "can't read from %s\n", gethostname_ex);
                pclose(fghn);
-                return -1;
-        }
-        if (pclose(fghn) == -1)
-                printerr(1, "pclose failed, continue\n");
+               return -1;
+       }
+       if (pclose(fghn) == -1)
+               printerr(LL_WARN, "pclose failed, continue\n");
 
-        /* trim head/tail space */
-        while (is_space(*head))
-                head++;
+       /* trim head/tail space */
+       while (is_space(*head))
+               head++;
 
-        tail = head + strlen(head);
+       tail = head + strlen(head);
        if (tail <= head) {
-                printerr(0, "no output from %s\n", gethostname_ex);
-                return -1;
-        }
-        while (is_space(*(tail - 1)))
-                tail--;
-        if (tail <= head) {
-                printerr(0, "output are all space from %s\n", gethostname_ex);
-                return -1;
-        }
-        *tail = '\0';
-
-        /* start with '@' means error msg */
-        if (head[0] == '@') {
-                printerr(0, "error from %s: %s\n", gethostname_ex, &head[1]);
-                return -1;
-        }
-
-        if (tail - head > namebuflen) {
-                printerr(0, "external hostname too long: %s\n", head);
-                return -1;
-        }
-
-        printerr(2, "%s: net 0x%x, addr 0x%x => %s\n",
-                 lnd, net, addr, head);
-        strcpy(namebuf, head);
-        return 0;
+               printerr(LL_ERR, "no output from %s\n", gethostname_ex);
+               return -1;
+       }
+       while (is_space(*(tail - 1)))
+               tail--;
+       if (tail <= head) {
+               printerr(LL_ERR, "output are all space from %s\n",
+                        gethostname_ex);
+               return -1;
+       }
+       *tail = '\0';
+
+       /* start with '@' means error msg */
+       if (head[0] == '@') {
+               printerr(LL_ERR, "error from %s: %s\n",
+                        gethostname_ex, &head[1]);
+               return -1;
+       }
+
+       if (tail - head > namebuflen) {
+               printerr(LL_ERR, "external hostname too long: %s\n", head);
+               return -1;
+       }
+
+       printerr(LL_INFO, "%s: net 0x%x, addr 0x%x => %s\n",
+                lnd, net, addr, head);
+       strcpy(namebuf, head);
+       return 0;
 }
 
 struct convert_struct {
@@ -303,25 +306,25 @@ static struct convert_struct converter[] = {
 
 int lnet_nid2hostname(lnet_nid_t nid, char *buf, int buflen)
 {
-        uint32_t lnd, net, addr;
+       uint32_t lnd, net, addr;
 
-        addr = LNET_NIDADDR(nid);
-        net = LNET_NIDNET(nid);
-        lnd = LNET_NETTYP(net);
+       addr = LNET_NIDADDR(nid);
+       net = LNET_NIDNET(nid);
+       lnd = LNET_NETTYP(net);
 
-        if (lnd >= LND_MAX) {
-                printerr(0, "ERROR: Unrecognized LND %u\n", lnd);
-                return -1;
-        }
+       if (lnd >= LND_MAX) {
+               printerr(LL_ERR, "ERROR: Unrecognized LND %u\n", lnd);
+               return -1;
+       }
 
-        if (converter[lnd].nid2name == NULL) {
-                printerr(0, "ERROR: %s converter not ready\n",
-                        converter[lnd].name);
-                return -1;
-        }
+       if (converter[lnd].nid2name == NULL) {
+               printerr(LL_ERR, "ERROR: %s converter not ready\n",
+                       converter[lnd].name);
+               return -1;
+       }
 
-        return converter[lnd].nid2name(converter[lnd].name, net, addr,
-                                       buf, buflen);
+       return converter[lnd].nid2name(converter[lnd].name, net, addr,
+                                      buf, buflen);
 }
 
 
@@ -362,30 +365,30 @@ void cleanup_mapping(void)
 
 static int grow_mapping(int nitems)
 {
-        struct user_map_item *new;
-        int oldsize, newsize;
-
-        oldsize = (mapping.nitems * sizeof(struct user_map_item) +
-                   MAPPING_GROW_SIZE - 1) / MAPPING_GROW_SIZE;
-        newsize = (nitems * sizeof(struct user_map_item) +
-                   MAPPING_GROW_SIZE - 1) / MAPPING_GROW_SIZE;
-        while (newsize <= oldsize)
-                return 0;
-
-        newsize *= MAPPING_GROW_SIZE;
-        new = malloc(newsize);
-        if (!new) {
-                printerr(0, "can't alloc mapping size %d\n", newsize);
-                return -1;
-        }
-
-        if (mapping.items) {
-                memcpy(new, mapping.items,
-                       mapping.nitems * sizeof(struct user_map_item));
-                free(mapping.items);
-        }
-        mapping.items = new;
-        return 0;
+       struct user_map_item *new;
+       int oldsize, newsize;
+
+       oldsize = (mapping.nitems * sizeof(struct user_map_item) +
+                  MAPPING_GROW_SIZE - 1) / MAPPING_GROW_SIZE;
+       newsize = (nitems * sizeof(struct user_map_item) +
+                  MAPPING_GROW_SIZE - 1) / MAPPING_GROW_SIZE;
+       while (newsize <= oldsize)
+               return 0;
+
+       newsize *= MAPPING_GROW_SIZE;
+       new = malloc(newsize);
+       if (!new) {
+               printerr(LL_ERR, "can't alloc mapping size %d\n", newsize);
+               return -1;
+       }
+
+       if (mapping.items) {
+               memcpy(new, mapping.items,
+                      mapping.nitems * sizeof(struct user_map_item));
+               free(mapping.items);
+       }
+       mapping.items = new;
+       return 0;
 }
 
 uid_t parse_uid(char *uidstr)
@@ -407,134 +410,148 @@ uid_t parse_uid(char *uidstr)
 
 static int read_mapping_db(void)
 {
-        char princ[MAX_LINE_LEN];
-        char nid_str[MAX_LINE_LEN];
-        char dest[MAX_LINE_LEN];
-        char linebuf[MAX_LINE_LEN];
-        char *line;
-        lnet_nid_t nid;
-        uid_t dest_uid;
-        FILE *f;
-
-        /* cleanup old mappings */
-        cleanup_mapping();
-
-        f = fopen(MAPPING_DATABASE_FILE, "r");
-        if (!f) {
-                printerr(0, "can't open mapping database: %s\n",
-                         MAPPING_DATABASE_FILE);
-                return -1;
-        }
-
-        while ((line = fgets(linebuf, MAX_LINE_LEN, f)) != NULL) {
-                char *name;
-
-                if (sscanf(line, "%s %s %s", princ, nid_str, dest) != 3) {
-                        printerr(0, "mapping db: syntax error\n");
-                        continue;
-                }
-
-                if (!strcmp(princ, "*")) {
-                        name = NULL;
-                } else {
-                        name = strdup(princ);
-                        if (!name) {
-                                printerr(0, "fail to dup str %s\n", princ);
-                                continue;
-                        }
-                }
-
-                if (!strcmp(nid_str, "*")) {
-                        nid = LNET_NID_ANY;
-                } else {
-                        nid = libcfs_str2nid(nid_str);
-                        if (nid == LNET_NID_ANY) {
-                                printerr(0, "fail to parse nid %s\n", nid_str);
-                                if (name)
-                                free(name);
-                                continue;
-                        }
-                }
-
-                dest_uid = parse_uid(dest);
-                if (dest_uid == -1) {
-                        printerr(0, "no valid user: %s\n", dest);
-                        if (name)
-                        free(name);
-                        continue;
-                }
-
-                if (grow_mapping(mapping.nitems + 1)) {
-                        printerr(0, "fail to grow mapping to %d\n",
-                                 mapping.nitems + 1);
-                        if (name)
-                        free(name);
-                        fclose(f);
-                        return -1;
-                }
-
-                mapping.items[mapping.nitems].principal = name;
-                mapping.items[mapping.nitems].nid = nid;
-                mapping.items[mapping.nitems].uid = dest_uid;
-                mapping.nitems++;
-                printerr(1, "add mapping: %s(%s/0x%llx) ==> %d\n",
-                         name, nid_str, nid, dest_uid);
-        }
-
-        fclose(f);
-        return 0;
+       char princ[MAX_LINE_LEN];
+       char nid_str[MAX_LINE_LEN];
+       char dest[MAX_LINE_LEN];
+       char linebuf[MAX_LINE_LEN];
+       char *line;
+       lnet_nid_t nid;
+       uid_t dest_uid;
+       FILE *f;
+
+       /* cleanup old mappings */
+       cleanup_mapping();
+
+       f = fopen(MAPPING_DATABASE_FILE, "r");
+       if (!f) {
+               printerr(LL_ERR, "can't open mapping database: %s\n",
+                        MAPPING_DATABASE_FILE);
+               return -1;
+       }
+
+       while ((line = fgets(linebuf, MAX_LINE_LEN, f)) != NULL) {
+               char *name;
+
+               if (sscanf(line, "%s %s %s", princ, nid_str, dest) != 3) {
+                       printerr(LL_ERR, "mapping db: syntax error\n");
+                       continue;
+               }
+
+               if (!strcmp(princ, "*")) {
+                       name = NULL;
+               } else {
+                       name = strdup(princ);
+                       if (!name) {
+                               printerr(LL_ERR, "fail to dup str %s\n", princ);
+                               continue;
+                       }
+               }
+
+               if (!strcmp(nid_str, "*")) {
+                       nid = LNET_NID_ANY;
+               } else {
+                       nid = libcfs_str2nid(nid_str);
+                       if (nid == LNET_NID_ANY) {
+                               printerr(LL_ERR, "fail to parse nid %s\n",
+                                        nid_str);
+                               if (name)
+                                       free(name);
+                               continue;
+                       }
+               }
+
+               dest_uid = parse_uid(dest);
+               if (dest_uid == -1) {
+                       printerr(LL_ERR, "no valid user: %s\n", dest);
+                       if (name)
+                               free(name);
+                       continue;
+               }
+
+               if (grow_mapping(mapping.nitems + 1)) {
+                       printerr(LL_ERR, "fail to grow mapping to %d\n",
+                                mapping.nitems + 1);
+                       if (name)
+                               free(name);
+                       fclose(f);
+                       return -1;
+               }
+
+               mapping.items[mapping.nitems].principal = name;
+               mapping.items[mapping.nitems].nid = nid;
+               mapping.items[mapping.nitems].uid = dest_uid;
+               mapping.nitems++;
+               printerr(LL_WARN, "add mapping: %s(%s/0x%llx) ==> %d\n",
+                        name, nid_str, nid, dest_uid);
+       }
+
+       fclose(f);
+       return 0;
 }
 
 static inline int mapping_changed(void)
 {
-        struct stat st;
-
-        if (stat(MAPPING_DATABASE_FILE, &st) == -1) {
-                /* stat failed, treat it like doesn't exist or be removed */
-                if (mapping_mtime == 0) {
-                        return 0;
-                } else {
-                        printerr(0, "Warning: stat %s failed: %s\n",
-                                 MAPPING_DATABASE_FILE, strerror(errno));
-
-                        mapping_mtime = 0;
-                        return 1;
-                }
-        }
+       struct stat st;
 
-        if (st.st_mtime != mapping_mtime) {
-                mapping_mtime = st.st_mtime;
-                return 1;
-        }
+       if (stat(MAPPING_DATABASE_FILE, &st) == -1) {
+               /* stat failed, treat it like doesn't exist or be removed */
+               if (mapping_mtime == 0)
+                       return 0;
 
-        return 0;
-}
+               printerr(LL_ERR, "stat %s failed: %s\n",
+                        MAPPING_DATABASE_FILE, strerror(errno));
 
-int lookup_mapping(char *princ, lnet_nid_t nid, uid_t *uid)
-{
-        int n;
+               mapping_mtime = 0;
+               return 1;
+       } else {
+               printerr(LL_WARN,
+                        "Use of idmap.conf is deprecated.\nPlease consider switching to auth_to_local or equivalent as provided by Kerberos for cross-realm trust remapping.\n");
+       }
 
-        *uid = -1;
+       if (st.st_mtime != mapping_mtime) {
+               mapping_mtime = st.st_mtime;
+               return 1;
+       }
 
-        /* FIXME race condition here */
-        if (mapping_changed()) {
-                if (read_mapping_db())
-                        printerr(0, "all remote users will be denied\n");
-        }
+       return 0;
+}
 
-        for (n = 0; n < mapping.nitems; n++) {
-                struct user_map_item *entry = &mapping.items[n];
-
-                if (entry->nid != LNET_NID_ANY && entry->nid != nid)
-                        continue;
-                if (!entry->principal || !strcasecmp(entry->principal, princ)) {
-                        printerr(1, "found mapping: %s ==> %d\n",
-                                 princ, entry->uid);
-                        *uid = entry->uid;
-                        return 0;
-                }
-        }
+void load_mapping(void)
+{
+       if (mapping_changed())
+               (void)read_mapping_db();
+}
 
-        printerr(2, "no mapping for %s/%#Lx\n", princ, nid);
-        return -1;
+int mapping_empty(void)
+{
+       return !mapping.nitems;
+}
+
+int lookup_mapping(char *princ, lnet_nid_t nid, uid_t *uid)
+{
+       int n;
+
+       *uid = -1;
+
+       /* FIXME race condition here */
+       if (mapping_changed()) {
+               if (read_mapping_db())
+                       printerr(LL_ERR, "all remote users will be denied\n");
+       }
+
+       for (n = 0; n < mapping.nitems; n++) {
+               struct user_map_item *entry = &mapping.items[n];
+
+               if (entry->nid != LNET_NID_ANY && entry->nid != nid)
+                       continue;
+               if (!entry->principal || !strcasecmp(entry->principal, princ)) {
+                       printerr(LL_WARN, "found mapping: %s ==> %d\n",
+                                princ, entry->uid);
+                       *uid = entry->uid;
+                       return 0;
+               }
+       }
+
+       printerr(LL_INFO, "no mapping for %s/%#Lx\n", princ, nid);
+       return -1;
 }
index 7a6ec0b..7e8cd4d 100644 (file)
@@ -102,6 +102,9 @@ struct lgssd_upcall_data {
 
 int lnet_nid2hostname(lnet_nid_t nid, char *buf, int buflen);
 void cleanup_mapping(void);
+uid_t parse_uid(char *uidstr);
+void load_mapping(void);
+int mapping_empty(void);
 int lookup_mapping(char *princ, lnet_nid_t nid, uid_t *uid);
 
 #endif /* __LSUPPORT_H__ */
index ab4c462..ff74036 100644 (file)
@@ -101,13 +101,13 @@ mydaemon(int nochdir, int noclose)
        int pid, status, tempfd;
 
        if (pipe(pipefds) < 0) {
-               printerr(1, "mydaemon: pipe() failed: errno %d (%s)\n",
-                       errno, strerror(errno));
+               printerr(LL_ERR, "%s: pipe() failed: errno %d (%s)\n",
+                        __func__, errno, strerror(errno));
                exit(1);
        }
        if ((pid = fork ()) < 0) {
-               printerr(1, "mydaemon: fork() failed: errno %d (%s)\n",
-                       errno, strerror(errno));
+               printerr(LL_ERR, "%s: fork() failed: errno %d (%s)\n",
+                        __func__, errno, strerror(errno));
                exit(1);
        }
 
@@ -125,8 +125,9 @@ mydaemon(int nochdir, int noclose)
        setsid ();
        if (nochdir == 0) {
                if (chdir ("/") == -1) {
-                       printerr(1, "mydaemon: chdir() failed: errno %d (%s)\n",
-                               errno, strerror(errno));
+                       printerr(LL_ERR,
+                                "%s: chdir() failed: errno %d (%s)\n",
+                                __func__, errno, strerror(errno));
                        exit(1);
                }
        }
@@ -134,8 +135,8 @@ mydaemon(int nochdir, int noclose)
        while (pipefds[1] <= 2) {
                pipefds[1] = dup(pipefds[1]);
                if (pipefds[1] < 0) {
-                       printerr(1, "mydaemon: dup() failed: errno %d (%s)\n",
-                               errno, strerror(errno));
+                       printerr(LL_ERR, "%s: dup() failed: errno %d (%s)\n",
+                                __func__, errno, strerror(errno));
                        exit(1);
                }
        }
@@ -167,7 +168,7 @@ sig_die(int signal)
 {
        /* destroy krb5 machine creds */
        cleanup_mapping();
-       printerr(1, "exiting on signal %d\n", signal);
+       printerr(LL_WARN, "exiting on signal %d\n", signal);
        exit(1);
 }
 
@@ -175,7 +176,7 @@ void
 sig_hup(int signal)
 {
        /* don't exit on SIGHUP */
-       printerr(1, "Received SIGHUP... Ignoring.\n");
+       printerr(LL_WARN, "Received SIGHUP... Ignoring.\n");
 }
 
 static void
@@ -276,22 +277,23 @@ main(int argc, char *argv[])
        /* For kerberos use gss mechanisms but ignore for sk and null */
        if (krb_enabled) {
                if (gssd_check_mechs()) {
-                       printerr(0, "ERROR: problem with gssapi library\n");
+                       printerr(LL_ERR,
+                                "ERROR: problem with gssapi library\n");
                        exit(1);
                }
                if (gssd_get_local_realm()) {
-                       printerr(0, "ERROR: Can't get Local Kerberos realm\n");
+                       printerr(LL_ERR,
+                                "ERROR: Can't get Local Kerberos realm\n");
                        exit(1);
                }
 
                if (get_creds &&
                    gssd_prepare_creds(must_srv_mgs, must_srv_mds,
                                       must_srv_oss)) {
-                       printerr(0, "unable to obtain root (machine) "
-                                "credentials\n");
-                       printerr(0, "do you have a keytab entry for "
-                                "<lustre_xxs>/<your.host>@<YOUR.REALM> in "
-                                "/etc/krb5.keytab?\n");
+                       printerr(LL_ERR,
+                                "unable to obtain root (machine) credentials\n");
+                       printerr(LL_ERR,
+                                "do you have a keytab entry for <lustre_xxs>/<your.host>@<YOUR.REALM> in /etc/krb5.keytab?\n");
                        exit(1);
                }
        }
@@ -314,6 +316,6 @@ main(int argc, char *argv[])
 
        svcgssd_run();
        cleanup_mapping();
-       printerr(0, "gssd_run returned!\n");
+       printerr(LL_ERR, "svcgssd_run returned!\n");
        abort();
 }
index 4d8bc13..64c32f5 100644 (file)
@@ -34,6 +34,7 @@
 #include <sys/types.h>
 #include <sys/queue.h>
 #include <gssapi/gssapi.h>
+#include "lsupport.h"
 
 int handle_channel_request(FILE *f);
 void svcgssd_run(void);
index ea28bcb..bbecd7f 100644 (file)
@@ -78,11 +78,15 @@ svcgssd_run()
                sk_dh_checks =
                        sk_speedtest_dh_valid(MAX_ALLOWED_TIME_FOR_PRIME);
                if (sk_dh_checks)
-                       printerr(1, "will use %d rounds for prime testing\n",
+                       printerr(LL_WARN,
+                                "will use %d rounds for prime testing\n",
                                 sk_dh_checks);
 #else
                sk_dh_checks = 0;
 #endif
+       } else {
+               /* For krb, preload mapping table if any */
+               load_mapping();
        }
 
        while (1) {
@@ -91,11 +95,11 @@ svcgssd_run()
                while (f == NULL) {
                        f = fopen(gss_rpc_channel_path, "r+");
                        if (f == NULL) {
-                               printerr(4, "failed to open %s: %s\n",
+                               printerr(LL_TRACE, "failed to open %s: %s\n",
                                         gss_rpc_channel_path, strerror(errno));
                                nanosleep(&halfsec, NULL);
                        } else {
-                               printerr(1, "successfully open %s\n",
+                               printerr(LL_WARN, "successfully open %s\n",
                                         gss_rpc_channel_path);
                                break;
                        }
@@ -108,16 +112,17 @@ svcgssd_run()
                save_err = errno;
 
                if (ret < 0) {
-                       printerr(0, "error return from poll: %s\n",
+                       printerr(LL_ERR, "error return from poll: %s\n",
                                 strerror(save_err));
                        fclose(f);
                        f = NULL;
                } else if (ret == 0) {
-                       printerr(4, "poll timeout\n");
+                       printerr(LL_TRACE, "poll timeout\n");
                } else {
                        if (ret != 1) {
-                               printerr(0, "bug: unexpected poll return %d\n",
-                                               ret);
+                               printerr(LL_ERR,
+                                        "bug: unexpected poll return %d\n",
+                                        ret);
                                exit(1);
                        }
                        if (pollfd.revents & POLLIN) {
index 87a0ad0..9931207 100644 (file)
@@ -60,6 +60,7 @@
 #include <linux/lustre/lustre_idl.h>
 #include "sk_utils.h"
 #include <sys/time.h>
+#include <gssapi/gssapi_krb5.h>
 
 #define SVCGSSD_CONTEXT_CHANNEL "/proc/net/rpc/auth.sptlrpc.context/channel"
 #define SVCGSSD_INIT_CHANNEL    "/proc/net/rpc/auth.sptlrpc.init/channel"
@@ -103,13 +104,13 @@ do_svc_downcall(gss_buffer_desc *out_handle, struct svc_cred *cred,
        const char *mechname;
        int err;
 
-       printerr(2, "doing downcall\n");
+       printerr(LL_INFO, "doing downcall\n");
        mechname = gss_OID_mech_name(mechoid);
        if (mechname == NULL)
                goto out_err;
        f = fopen(SVCGSSD_CONTEXT_CHANNEL, "w");
        if (f == NULL) {
-               printerr(0, "WARNING: unable to open downcall channel "
+               printerr(LL_ERR, "ERROR: unable to open downcall channel "
                             "%s: %s\n",
                             SVCGSSD_CONTEXT_CHANNEL, strerror(errno));
                goto out_err;
@@ -130,7 +131,7 @@ do_svc_downcall(gss_buffer_desc *out_handle, struct svc_cred *cred,
        fclose(f);
        return err;
 out_err:
-       printerr(0, "WARNING: downcall failed\n");
+       printerr(LL_ERR, "ERROR: downcall failed\n");
        return -1;
 }
 
@@ -152,7 +153,7 @@ send_response(FILE *f, gss_buffer_desc *in_handle, gss_buffer_desc *in_token,
        /* XXXARG: */
        int g;
 
-       printerr(2, "sending reply\n");
+       printerr(LL_INFO, "sending reply\n");
        qword_addhex(&bp, &blen, in_handle->value, in_handle->length);
        qword_addhex(&bp, &blen, in_token->value, in_token->length);
        qword_addint(&bp, &blen, time(NULL) + 3600);   /* 1 hour should be ok */
@@ -162,19 +163,20 @@ send_response(FILE *f, gss_buffer_desc *in_handle, gss_buffer_desc *in_token,
        qword_addhex(&bp, &blen, out_token->value, out_token->length);
        qword_addeol(&bp, &blen);
        if (blen <= 0) {
-               printerr(0, "WARNING: send_response: message too long\n");
+               printerr(LL_ERR, "ERROR: %s: message too long\n", __func__);
                return -1;
        }
        g = open(SVCGSSD_INIT_CHANNEL, O_WRONLY);
        if (g == -1) {
-               printerr(0, "WARNING: open %s failed: %s\n",
-                               SVCGSSD_INIT_CHANNEL, strerror(errno));
+               printerr(LL_ERR, "ERROR: %s: open %s failed: %s\n",
+                        __func__, SVCGSSD_INIT_CHANNEL, strerror(errno));
                return -1;
        }
        *bp = '\0';
-       printerr(3, "writing message: %s", buf);
+       printerr(LL_DEBUG, "writing message: %s", buf);
        if (write(g, buf, bp - buf) == -1) {
-               printerr(0, "WARNING: failed to write message\n");
+               printerr(LL_ERR, "ERROR: %s: failed to write message\n",
+                        __func__);
                close(g);
                return -1;
        }
@@ -191,6 +193,50 @@ send_response(FILE *f, gss_buffer_desc *in_handle, gss_buffer_desc *in_token,
 #define rpcsec_gsserr_credproblem      13
 #define rpcsec_gsserr_ctxproblem       14
 
+static int lookup_localname(gss_name_t client_name, char *princ, lnet_nid_t nid,
+                           uid_t *uid)
+{
+       u_int32_t maj_stat, min_stat;
+       gss_buffer_desc localname;
+       char *sname;
+       int rc = -1;
+
+       *uid = -1;
+       maj_stat = gss_localname(&min_stat, client_name, GSS_C_NO_OID,
+                                &localname);
+       if (maj_stat != GSS_S_COMPLETE) {
+               printerr(LL_INFO, "no local name for %s/%#Lx\n", princ, nid);
+               return rc;
+       }
+
+       sname = calloc(localname.length + 1, 1);
+       if (!sname) {
+               printerr(LL_ERR, "%s: error allocating %zu bytes\n",
+                        __func__, localname.length + 1);
+               goto free;
+       }
+       memcpy(sname, localname.value, localname.length);
+       sname[localname.length] = '\0';
+
+       *uid = parse_uid(sname);
+       free(sname);
+       printerr(LL_WARN, "found local uid: %s ==> %d\n", princ, *uid);
+       rc = 0;
+
+free:
+       gss_release_buffer(&min_stat, &localname);
+       return rc;
+}
+
+static int lookup_id(gss_name_t client_name, char *princ, lnet_nid_t nid,
+                    uid_t *uid)
+{
+       if (!mapping_empty())
+               return lookup_mapping(princ, nid, uid);
+
+       return lookup_localname(client_name, princ, nid, uid);
+}
+
 static int
 get_ids(gss_name_t client_name, gss_OID mech, struct svc_cred *cred,
        lnet_nid_t nid, uint32_t lustre_svc)
@@ -214,10 +260,12 @@ get_ids(gss_name_t client_name, gss_OID mech, struct svc_cred *cred,
                        maj_stat, min_stat, mech);
                return -1;
        }
-       if (name.length >= 0xffff || /* be certain name.length+1 doesn't overflow */
+       /* be certain name.length+1 doesn't overflow */
+       if (name.length >= 0xffff ||
            !(sname = calloc(name.length + 1, 1))) {
-               printerr(0, "WARNING: get_ids: error allocating %zu bytes "
-                       "for sname\n", name.length + 1);
+               printerr(LL_ERR,
+                        "ERROR: %s: error allocating %zu bytes for sname\n",
+                        __func__, name.length + 1);
                gss_release_buffer(&min_stat, &name);
                return -1;
        }
@@ -225,16 +273,15 @@ get_ids(gss_name_t client_name, gss_OID mech, struct svc_cred *cred,
        sname[name.length] = '\0';
        gss_release_buffer(&min_stat, &name);
 
-       if (lustre_svc == LUSTRE_GSS_SVC_MDS)
-               lookup_mapping(sname, nid, &cred->cr_mapped_uid);
-       else
-               cred->cr_mapped_uid = -1;
+       if (lustre_svc == LUSTRE_GSS_SVC_MDS &&
+           lookup_id(client_name, sname, nid, &cred->cr_mapped_uid))
+               printerr(LL_DEBUG, "no id found for %s\n", sname);
 
        realm = strchr(sname, '@');
        if (realm) {
                *realm++ = '\0';
        } else {
-               printerr(0, "ERROR: %s has no realm name\n", sname);
+               printerr(LL_ERR, "ERROR: %s has no realm name\n", sname);
                goto out_free;
        }
 
@@ -243,30 +290,32 @@ get_ids(gss_name_t client_name, gss_OID mech, struct svc_cred *cred,
                *host++ = '\0';
 
        if (strcmp(sname, GSSD_SERVICE_MGS) == 0) {
-               printerr(0, "forbid %s as a user name\n", sname);
+               printerr(LL_ERR, "forbid %s as a user name\n", sname);
                goto out_free;
        }
 
        /* 1. check host part */
        if (host) {
                if (lnet_nid2hostname(nid, namebuf, namebuf_size)) {
-                       printerr(0, "ERROR: failed to resolve hostname for "
-                                "%s/%s@%s from %016llx\n",
+                       printerr(LL_ERR,
+                                "ERROR: failed to resolve hostname for %s/%s@%s from %016llx\n",
                                 sname, host, realm, nid);
                        goto out_free;
                }
 
                if (strcasecmp(host, namebuf)) {
-                       printerr(0, "ERROR: %s/%s@%s claimed hostname doesn't "
-                                "match %s, nid %016llx\n", sname, host, realm,
+                       printerr(LL_ERR,
+                                "ERROR: %s/%s@%s claimed hostname doesn't match %s, nid %016llx\n",
+                                sname, host, realm,
                                 namebuf, nid);
                        goto out_free;
                }
        } else {
                if (!strcmp(sname, GSSD_SERVICE_MDS) ||
                    !strcmp(sname, GSSD_SERVICE_OSS)) {
-                       printerr(0, "ERROR: %s@%s from %016llx doesn't "
-                                "bind with hostname\n", sname, realm, nid);
+                       printerr(LL_ERR,
+                                "ERROR: %s@%s from %016llx doesn't bind with hostname\n",
+                                sname, realm, nid);
                        goto out_free;
                }
        }
@@ -274,46 +323,57 @@ get_ids(gss_name_t client_name, gss_OID mech, struct svc_cred *cred,
        /* 2. check realm and user */
        switch (lustre_svc) {
        case LUSTRE_GSS_SVC_MDS:
-               if (strcasecmp(mds_local_realm, realm)) {
+               if (strcasecmp(mds_local_realm, realm) != 0) {
+                       /* Remote realm case */
                        cred->cr_remote = 1;
 
-                       /* only allow mapped user from remote realm */
+                       /* Prevent access to unmapped user from remote realm */
                        if (cred->cr_mapped_uid == -1) {
-                               printerr(0, "ERROR: %s%s%s@%s from %016llx "
-                                        "is remote but without mapping\n",
+                               printerr(LL_ERR,
+                                        "ERROR: %s%s%s@%s from %016llx is remote but without mapping\n",
                                         sname, host ? "/" : "",
                                         host ? host : "", realm, nid);
                                break;
                        }
-               } else {
-                       if (!strcmp(sname, LUSTRE_ROOT_NAME)) {
-                               cred->cr_uid = 0;
-                               cred->cr_usr_root = 1;
-                       } else if (!strcmp(sname, GSSD_SERVICE_MDS)) {
-                               cred->cr_uid = 0;
-                               cred->cr_usr_mds = 1;
-                       } else if (!strcmp(sname, GSSD_SERVICE_OSS)) {
-                               cred->cr_uid = 0;
-                               cred->cr_usr_oss = 1;
-                       } else {
-                               pw = getpwnam(sname);
-                               if (pw != NULL) {
-                                       cred->cr_uid = pw->pw_uid;
-                                       printerr(2, "%s resolve to uid %u\n",
-                                                sname, cred->cr_uid);
-                               } else if (cred->cr_mapped_uid != -1) {
-                                       printerr(2, "user %s from %016llx is "
-                                                "mapped to %u\n", sname, nid,
-                                                cred->cr_mapped_uid);
-                               } else {
-                                       printerr(0, "ERROR: invalid user, "
-                                                "%s/%s@%s from %016llx\n",
-                                                sname, host, realm, nid);
-                                       break;
-                               }
-                       }
+                       goto valid;
                }
 
+               /* Now we know we are dealing with a local realm */
+
+               if (!strcmp(sname, LUSTRE_ROOT_NAME)) {
+                       cred->cr_uid = 0;
+                       cred->cr_usr_root = 1;
+                       goto valid;
+               }
+               if (!strcmp(sname, GSSD_SERVICE_MDS)) {
+                       cred->cr_uid = 0;
+                       cred->cr_usr_mds = 1;
+                       goto valid;
+               }
+               if (!strcmp(sname, GSSD_SERVICE_OSS)) {
+                       cred->cr_uid = 0;
+                       cred->cr_usr_oss = 1;
+                       goto valid;
+               }
+               if (cred->cr_mapped_uid != -1) {
+                       printerr(LL_INFO,
+                                "user %s from %016llx is mapped to %u\n",
+                                sname, nid,
+                                cred->cr_mapped_uid);
+                       goto valid;
+               }
+               pw = getpwnam(sname);
+               if (pw != NULL) {
+                       cred->cr_uid = pw->pw_uid;
+                       printerr(LL_INFO, "%s resolve to uid %u\n",
+                                sname, cred->cr_uid);
+                       goto valid;
+               }
+               printerr(LL_ERR, "ERROR: invalid user, %s/%s@%s from %016llx\n",
+                        sname, host, realm, nid);
+               break;
+
+valid:
                res = 0;
                break;
        case LUSTRE_GSS_SVC_MGS:
@@ -331,8 +391,9 @@ get_ids(gss_name_t client_name, gss_OID mech, struct svc_cred *cred,
                        cred->cr_usr_mds = 1;
                }
                if (cred->cr_uid == -1) {
-                       printerr(0, "ERROR: svc %d doesn't accept user %s "
-                                "from %016llx\n", lustre_svc, sname, nid);
+                       printerr(LL_ERR,
+                                "ERROR: svc %d doesn't accept user %s from %016llx\n",
+                                lustre_svc, sname, nid);
                        break;
                }
                res = 0;
@@ -343,7 +404,7 @@ get_ids(gss_name_t client_name, gss_OID mech, struct svc_cred *cred,
 
 out_free:
        if (!res)
-               printerr(1, "%s: authenticated %s%s%s@%s from %016llx\n",
+               printerr(LL_WARN, "%s: authenticated %s%s%s@%s from %016llx\n",
                         lustre_svc_name[lustre_svc], sname,
                         host ? "/" : "", host ? host : "", realm, nid);
        free(sname);
@@ -369,26 +430,27 @@ int handle_sk(struct svc_nego_data *snd)
        int i;
        int attempts = 0;
 
-       printerr(3, "Handling sk request\n");
+       printerr(LL_DEBUG, "Handling sk request\n");
        memset(bufs, 0, sizeof(gss_buffer_desc) * SK_INIT_BUFFERS);
 
        /* See lgss_sk_using_cred() for client side token formation.
         * Decoding initiator buffers */
        i = sk_decode_netstring(bufs, SK_INIT_BUFFERS, &snd->in_tok);
        if (i < SK_INIT_BUFFERS) {
-               printerr(0, "Invalid netstring token received from peer\n");
+               printerr(LL_ERR,
+                        "Invalid netstring token received from peer\n");
                goto cleanup_buffers;
        }
 
        /* Allowing for a larger length first buffer in the future */
        if (bufs[SK_INIT_VERSION].length < sizeof(version)) {
-               printerr(0, "Invalid version received (wrong size)\n");
+               printerr(LL_ERR, "Invalid version received (wrong size)\n");
                goto cleanup_buffers;
        }
        memcpy(&version, bufs[SK_INIT_VERSION].value, sizeof(version));
        version = be32toh(version);
        if (version != SK_MSG_VERSION) {
-               printerr(0, "Invalid version received: %d\n", version);
+               printerr(LL_ERR, "Invalid version received: %d\n", version);
                goto cleanup_buffers;
        }
 
@@ -398,19 +460,19 @@ int handle_sk(struct svc_nego_data *snd)
        i = bufs[SK_INIT_TARGET].length - 1;
        target = bufs[SK_INIT_TARGET].value;
        if (i >= 0 && target[i] != '\0') {
-               printerr(0, "Invalid target from netstring\n");
+               printerr(LL_ERR, "Invalid target from netstring\n");
                goto cleanup_buffers;
        }
 
        if (bufs[SK_INIT_FLAGS].length != sizeof(flags)) {
-               printerr(0, "Invalid flags from netstring\n");
+               printerr(LL_ERR, "Invalid flags from netstring\n");
                goto cleanup_buffers;
        }
        memcpy(&flags, bufs[SK_INIT_FLAGS].value, sizeof(flags));
 
        skc = sk_create_cred(target, snd->nm_name, be32toh(flags));
        if (!skc) {
-               printerr(0, "Failed to create sk credentials\n");
+               printerr(LL_ERR, "Failed to create sk credentials\n");
                goto cleanup_buffers;
        }
 
@@ -420,8 +482,9 @@ int handle_sk(struct svc_nego_data *snd)
         * servers */
        if (skc->sc_flags & LGSS_SVC_PRIV &&
            bufs[SK_INIT_P].length < skc->sc_p.length) {
-               printerr(0, "Peer DHKE prime does not meet the size required "
-                        "by keyfile: %zd bits\n", skc->sc_p.length * 8);
+               printerr(LL_ERR,
+                        "Peer DHKE prime does not meet the size required by keyfile: %zd bits\n",
+                        skc->sc_p.length * 8);
                goto cleanup_buffers;
        }
 
@@ -433,7 +496,7 @@ int handle_sk(struct svc_nego_data *snd)
        /* Take control of all the allocated buffers from decoding */
        if (bufs[SK_INIT_RANDOM].length !=
            sizeof(skc->sc_kctx.skc_peer_random)) {
-               printerr(0, "Invalid size for client random\n");
+               printerr(LL_ERR, "Invalid size for client random\n");
                goto cleanup_buffers;
        }
 
@@ -450,7 +513,7 @@ int handle_sk(struct svc_nego_data *snd)
        rc = sk_verify_hmac(skc, bufs, SK_INIT_BUFFERS - 1, EVP_sha256(),
                            &skc->sc_hmac);
        if (rc != GSS_S_COMPLETE) {
-               printerr(0, "HMAC verification error: 0x%x from peer %s\n",
+               printerr(LL_ERR, "HMAC verification error: 0x%x from peer %s\n",
                         rc, libcfs_nid2str((lnet_nid_t)snd->nid));
                goto cleanup_partial;
        }
@@ -458,14 +521,15 @@ int handle_sk(struct svc_nego_data *snd)
        /* Check that the cluster hash matches the hash of nodemap name */
        rc = sk_verify_hash(snd->nm_name, EVP_sha256(), &skc->sc_nodemap_hash);
        if (rc != GSS_S_COMPLETE) {
-               printerr(0, "Cluster hash failed validation: 0x%x\n", rc);
+               printerr(LL_ERR, "Cluster hash failed validation: 0x%x\n", rc);
                goto cleanup_partial;
        }
 
 redo:
        rc = sk_gen_params(skc, sk_dh_checks);
        if (rc != GSS_S_COMPLETE) {
-               printerr(0, "Failed to generate DH params for responder\n");
+               printerr(LL_ERR,
+                        "Failed to generate DH params for responder\n");
                goto cleanup_partial;
        }
        rc = sk_compute_dh_key(skc, &remote_pub_key);
@@ -493,7 +557,8 @@ redo:
                skc->sc_dh_shared_key.length = 0;
                goto redo;
        } else if (rc != GSS_S_COMPLETE) {
-               printerr(0, "Failed to compute session key from DH params\n");
+               printerr(LL_ERR,
+                        "Failed to compute session key from DH params\n");
                goto cleanup_partial;
        }
 
@@ -513,26 +578,28 @@ redo:
        if (sk_sign_bufs(&skc->sc_kctx.skc_shared_key, bufs,
                         SK_RESP_BUFFERS - 1, EVP_sha256(),
                         &skc->sc_hmac)) {
-               printerr(0, "Failed to sign parameters\n");
+               printerr(LL_ERR, "Failed to sign parameters\n");
                goto out_err;
        }
        bufs[SK_RESP_HMAC] = skc->sc_hmac;
        if (sk_encode_netstring(bufs, SK_RESP_BUFFERS, &snd->out_tok)) {
-               printerr(0, "Failed to encode netstring for token\n");
+               printerr(LL_ERR, "Failed to encode netstring for token\n");
                goto out_err;
        }
-       printerr(2, "Created netstring of %zd bytes\n", snd->out_tok.length);
+       printerr(LL_INFO, "Created netstring of %zd bytes\n",
+                snd->out_tok.length);
 
        if (sk_session_kdf(skc, snd->nid, &snd->in_tok, &snd->out_tok)) {
-               printerr(0, "Failed to calculate derived session key\n");
+               printerr(LL_ERR, "Failed to calculate derived session key\n");
                goto out_err;
        }
        if (sk_compute_keys(skc)) {
-               printerr(0, "Failed to compute HMAC and encryption keys\n");
+               printerr(LL_ERR,
+                        "Failed to compute HMAC and encryption keys\n");
                goto out_err;
        }
        if (sk_serialize_kctx(skc, &snd->ctx_token)) {
-               printerr(0, "Failed to serialize context for kernel\n");
+               printerr(LL_ERR, "Failed to serialize context for kernel\n");
                goto out_err;
        }
 
@@ -559,7 +626,7 @@ redo:
        free(snd->ctx_token.value);
        snd->ctx_token.length = 0;
 
-       printerr(3, "sk returning success\n");
+       printerr(LL_DEBUG, "sk returning success\n");
        return 0;
 
 cleanup_buffers:
@@ -588,9 +655,9 @@ out_err:
        }
        free(remote_pub_key.value);
        sk_free_cred(skc);
-       printerr(3, "sk returning failure\n");
+       printerr(LL_DEBUG, "sk returning failure\n");
 #else /* !HAVE_OPENSSL_SSK */
-       printerr(0, "ERROR: shared key subflavour is not enabled\n");
+       printerr(LL_ERR, "ERROR: shared key subflavour is not enabled\n");
 #endif /* HAVE_OPENSSL_SSK */
        return -1;
 }
@@ -605,7 +672,7 @@ int handle_null(struct svc_nego_data *snd)
         * for sending to the kernel.  It is a single uint64_t. */
        if (snd->in_tok.length != sizeof(uint64_t)) {
                snd->maj_stat = GSS_S_DEFECTIVE_TOKEN;
-               printerr(0, "Invalid token size (%zd) received\n",
+               printerr(LL_ERR, "Invalid token size (%zd) received\n",
                         snd->in_tok.length);
                return -1;
        }
@@ -613,7 +680,7 @@ int handle_null(struct svc_nego_data *snd)
        snd->out_tok.value = malloc(snd->out_tok.length);
        if (!snd->out_tok.value) {
                snd->maj_stat = GSS_S_FAILURE;
-               printerr(0, "Failed to allocate out_tok\n");
+               printerr(LL_ERR, "Failed to allocate out_tok\n");
                return -1;
        }
 
@@ -621,7 +688,7 @@ int handle_null(struct svc_nego_data *snd)
        snd->ctx_token.value = malloc(snd->ctx_token.length);
        if (!snd->ctx_token.value) {
                snd->maj_stat = GSS_S_FAILURE;
-               printerr(0, "Failed to allocate ctx_token\n");
+               printerr(LL_ERR, "Failed to allocate ctx_token\n");
                return -1;
        }
 
@@ -664,7 +731,7 @@ static int handle_krb(struct svc_nego_data *snd)
 
        svc_cred = gssd_select_svc_cred(snd->lustre_svc);
        if (!svc_cred) {
-               printerr(0, "no service credential for svc %u\n",
+               printerr(LL_ERR, "no service credential for svc %u\n",
                         snd->lustre_svc);
                goto out_err;
        }
@@ -677,14 +744,15 @@ static int handle_krb(struct svc_nego_data *snd)
                                               NULL);
 
        if (snd->maj_stat == GSS_S_CONTINUE_NEEDED) {
-               printerr(1, "gss_accept_sec_context GSS_S_CONTINUE_NEEDED\n");
+               printerr(LL_WARN,
+                        "gss_accept_sec_context GSS_S_CONTINUE_NEEDED\n");
 
                /* Save the context handle for future calls */
                snd->out_handle.length = sizeof(snd->ctx);
                memcpy(snd->out_handle.value, &snd->ctx, sizeof(snd->ctx));
                return 0;
        } else if (snd->maj_stat != GSS_S_COMPLETE) {
-               printerr(0, "WARNING: gss_accept_sec_context failed\n");
+               printerr(LL_ERR, "ERROR: gss_accept_sec_context failed\n");
                pgsserr("handle_krb: gss_accept_sec_context",
                        snd->maj_stat, snd->min_stat, mech);
                goto out_err;
@@ -707,8 +775,9 @@ static int handle_krb(struct svc_nego_data *snd)
        /* kernel needs ctx to calculate verifier on null response, so
         * must give it context before doing null call: */
        if (serialize_context_for_kernel(snd->ctx, &snd->ctx_token, mech)) {
-               printerr(0, "WARNING: handle_krb: "
-                        "serialize_context_for_kernel failed\n");
+               printerr(LL_ERR,
+                        "ERROR: %s: serialize_context_for_kernel failed\n",
+                       __func__);
                snd->maj_stat = GSS_S_FAILURE;
                goto out_err;
        }
@@ -752,9 +821,9 @@ int handle_channel_request(FILE *f)
                .ctx                    = GSS_C_NO_CONTEXT,
        };
 
-       printerr(2, "handling request\n");
+       printerr(LL_INFO, "handling request\n");
        if (readline(fileno(f), &lbuf, &lbuflen) != 1) {
-               printerr(0, "WARNING: failed reading request\n");
+               printerr(LL_ERR, "ERROR: failed reading request\n");
                return -1;
        }
 
@@ -773,8 +842,8 @@ int handle_channel_request(FILE *f)
                        static time_t next_krb;
 
                        if (time(NULL) > next_krb) {
-                               printerr(1, "warning: Request for kerberos but "
-                                        "service support not enabled\n");
+                               printerr(LL_WARN,
+                                        "warning: Request for kerberos but service support not enabled\n");
                                next_krb = time(NULL) + 3600;
                        }
                        goto ignore;
@@ -786,8 +855,8 @@ int handle_channel_request(FILE *f)
                        static time_t next_null;
 
                        if (time(NULL) > next_null) {
-                               printerr(1, "warning: Request for gssnull but "
-                                        "service support not enabled\n");
+                               printerr(LL_WARN,
+                                        "warning: Request for gssnull but service support not enabled\n");
                                next_null = time(NULL) + 3600;
                        }
                        goto ignore;
@@ -799,8 +868,8 @@ int handle_channel_request(FILE *f)
                        static time_t next_ssk;
 
                        if (time(NULL) > next_ssk) {
-                               printerr(1, "warning: Request for SSK but "
-                                        "service support not %s\n",
+                               printerr(LL_WARN,
+                                        "warning: Request for SSK but service support not %s\n",
 #ifdef HAVE_OPENSSL_SSK
                                         "enabled"
 #else
@@ -815,7 +884,7 @@ int handle_channel_request(FILE *f)
                snd.mech = &skoid;
                break;
        default:
-               printerr(0, "WARNING: invalid mechanism recevied: %d\n",
+               printerr(LL_ERR, "WARNING: invalid mechanism recevied: %d\n",
                         lustre_mech);
                goto out_err;
                break;
@@ -824,33 +893,35 @@ int handle_channel_request(FILE *f)
        qword_get(&cp, (char *)&snd.nid, sizeof(snd.nid));
        qword_get(&cp, (char *)&snd.handle_seq, sizeof(snd.handle_seq));
        qword_get(&cp, snd.nm_name, sizeof(snd.nm_name));
-       printerr(2, "handling req: svc %u, nid %016llx, idx %"PRIx64" nodemap "
-                "%s\n", snd.lustre_svc, snd.nid, snd.handle_seq, snd.nm_name);
+       printerr(LL_INFO,
+                "handling req: svc %u, nid %016llx, idx %"PRIx64" nodemap %s\n",
+                snd.lustre_svc, snd.nid, snd.handle_seq, snd.nm_name);
 
        get_len = qword_get(&cp, snd.in_handle.value, sizeof(in_handle_buf));
        if (get_len < 0) {
-               printerr(0, "WARNING: failed parsing request\n");
+               printerr(LL_ERR, "ERROR: failed parsing request\n");
                goto out_err;
        }
        snd.in_handle.length = (size_t)get_len;
 
-       printerr(3, "in_handle:\n");
+       printerr(LL_DEBUG, "in_handle:\n");
        print_hexl(3, snd.in_handle.value, snd.in_handle.length);
 
        get_len = qword_get(&cp, snd.in_tok.value, sizeof(in_tok_buf));
        if (get_len < 0) {
-               printerr(0, "WARNING: failed parsing request\n");
+               printerr(LL_ERR, "ERROR: failed parsing request\n");
                goto out_err;
        }
        snd.in_tok.length = (size_t)get_len;
 
-       printerr(3, "in_tok:\n");
+       printerr(LL_DEBUG, "in_tok:\n");
        print_hexl(3, snd.in_tok.value, snd.in_tok.length);
 
        if (snd.in_handle.length != 0) { /* CONTINUE_INIT case */
                if (snd.in_handle.length != sizeof(snd.ctx)) {
-                       printerr(0, "WARNING: input handle has unexpected "
-                                "length %zu\n", snd.in_handle.length);
+                       printerr(LL_ERR,
+                                "ERROR: input handle has unexpected length %zu\n",
+                                snd.in_handle.length);
                        goto out_err;
                }
                /* in_handle is the context id stored in the out_handle
@@ -865,8 +936,8 @@ int handle_channel_request(FILE *f)
        else if (lustre_mech == LGSS_MECH_NULL)
                rc = handle_null(&snd);
        else
-               printerr(0,
-                        "WARNING: Received or request for subflavor that is not enabled: %d\n",
+               printerr(LL_ERR,
+                        "ERROR: Received or request for subflavor that is not enabled: %d\n",
                         lustre_mech);
 
 out_err: