diff options
| author | Dante Catalfamo | 2021-05-29 21:08:18 -0400 | 
|---|---|---|
| committer | Dante Catalfamo | 2021-05-29 21:08:18 -0400 | 
| commit | 8391d75b6ee4d2d71d2208838aa44e09a61f2e62 (patch) | |
| tree | 5eab76b0178234edc5f71652ec4e0d40aa7528c7 /content/posts/WIP-how-bsd-authentication-works | |
| parent | b868ffba6a72f3cb626fcac9692d261a022452dd (diff) | |
| download | blog-8391d75b6ee4d2d71d2208838aa44e09a61f2e62.tar.gz blog-8391d75b6ee4d2d71d2208838aa44e09a61f2e62.tar.bz2 blog-8391d75b6ee4d2d71d2208838aa44e09a61f2e62.zip | |
bsd-auth: add auth_approval definition
Diffstat (limited to 'content/posts/WIP-how-bsd-authentication-works')
| -rw-r--r-- | content/posts/WIP-how-bsd-authentication-works/index.org | 149 | 
1 files changed, 149 insertions, 0 deletions
| diff --git a/content/posts/WIP-how-bsd-authentication-works/index.org b/content/posts/WIP-how-bsd-authentication-works/index.org index ec601ce..fce6768 100644 --- a/content/posts/WIP-how-bsd-authentication-works/index.org +++ b/content/posts/WIP-how-bsd-authentication-works/index.org @@ -2146,6 +2146,155 @@    If a username is invalid, it is logged in the syslog. +* auth_approval +  :PROPERTIES: +  :CUSTOM_ID: auth_approval +  :END: + +  @@html: <details> <summary> @@ +  #+begin_src c +  int auth_approval(auth_session_t *as, login_cap_t *lc, char *name, char *type) +  #+end_src +  @@html: </summary> @@ +  #+begin_src c +  { +      int close_on_exit, close_lc_on_exit, len; +      struct passwd pwstore, *pwd; +      char *approve, *s, path[PATH_MAX], pwbuf[_PW_BUF_LEN]; + +      pwd = NULL; +      close_on_exit = as == NULL; +      close_lc_on_exit = lc == NULL; + +      if (as != NULL && name == NULL) +          name = auth_getitem(as, AUTHV_NAME); + +      if (as != NULL) +          pwd = auth_getpwd(as); + +      if (pwd == NULL) { +          if (name != NULL) { +              if (!_auth_validuser(name)) { +                  warnx("cannot approve who we don't recognize"); +                  return (0); +              } +              getpwnam_r(name, &pwstore, pwbuf, sizeof(pwbuf), &pwd); +          } else { +              getpwuid_r(getuid(), &pwstore, pwbuf, sizeof(pwbuf), +                  &pwd); +              if (pwd == NULL) { +                  syslog(LOG_ERR, "no such user id %u", getuid()); +                  warnx("cannot approve who we don't recognize"); +                  return (0); +              } +              name = pwd->pw_name; +          } +      } + +      if (name == NULL) +          name = pwd->pw_name; + +      if (lc == NULL) { +          if (strlen(name) >= PATH_MAX) { +              syslog(LOG_ERR, "username to login %.*s...", +                  PATH_MAX, name); +              warnx("username too long"); +              return (0); +          } +          if (pwd == NULL && (approve = strchr(name, '.')) != NULL) { +              strlcpy(path, name, sizeof path); +              path[approve - name] = '\0'; +              getpwnam_r(name, &pwstore, pwbuf, sizeof(pwbuf), &pwd); +          } +          lc = login_getclass(pwd ? pwd->pw_class : NULL); +          if (lc == NULL) { +              warnx("unable to classify user"); +              return (0); +          } +      } + +      if (!type) +          type = LOGIN_DEFSERVICE; +      else { +          if (strncmp(type, "approve-", 8) == 0) +              type += 8; + +          len = snprintf(path, sizeof(path), "approve-%s", type); +          if (len < 0 || len >= sizeof(path)) { +              if (close_lc_on_exit) +                  login_close(lc); +              syslog(LOG_ERR, "approval path too long %.*s...", +                  PATH_MAX, type); +              warnx("approval script path too long"); +              return (0); +          } +      } + +      if ((approve = login_getcapstr(lc, s = path, NULL, NULL)) == NULL) +          approve = login_getcapstr(lc, s = "approve", NULL, NULL); + +      if (approve && approve[0] != '/') { +          if (close_lc_on_exit) +              login_close(lc); +          syslog(LOG_ERR, "Invalid %s script: %s", s, approve); +          warnx("invalid path to approval script"); +          free(approve); +          return (0); +      } + +      if (as == NULL && (as = auth_open()) == NULL) { +          if (close_lc_on_exit) +              login_close(lc); +          syslog(LOG_ERR, "%m"); +          warn(NULL); +          free(approve); +          return (0); +      } + +      auth_setstate(as, AUTH_OKAY); +      if (auth_setitem(as, AUTHV_NAME, name) < 0) { +          syslog(LOG_ERR, "%m"); +          warn(NULL); +          goto out; +      } +      if (auth_check_expire(as) < 0)	/* is this account expired */ +          goto out; +      if (_auth_checknologin(lc, +          auth_getitem(as, AUTHV_INTERACTIVE) != NULL)) { +          auth_setstate(as, (auth_getstate(as) & ~AUTH_ALLOW)); +          goto out; +      } +      if (login_getcapbool(lc, "requirehome", 0) && pwd && pwd->pw_dir && +          pwd->pw_dir[0]) { +          struct stat sb; + +          if (stat(pwd->pw_dir, &sb) == -1 || !S_ISDIR(sb.st_mode) || +              (pwd->pw_uid && sb.st_uid == pwd->pw_uid && +              (sb.st_mode & S_IXUSR) == 0)) { +              auth_setstate(as, (auth_getstate(as) & ~AUTH_ALLOW)); +              goto out; +          } +      } +      if (approve) +          auth_call(as, approve, strrchr(approve, '/') + 1, "--", name, +              lc->lc_class, type, (char *)NULL); + +  out: +      free(approve); +      if (close_lc_on_exit) +          login_close(lc); + +      if (close_on_exit) +          return (auth_close(as)); +      return (auth_getstate(as) & AUTH_ALLOW); +  } +  #+end_src +  @@html: </details> @@ + +  =auth_approval= is + +  <<here>> +  * COMMENT note                                                     :noexport:   --- | 
