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 | |
parent | b868ffba6a72f3cb626fcac9692d261a022452dd (diff) | |
download | blog-8391d75b6ee4d2d71d2208838aa44e09a61f2e62.tar.gz blog-8391d75b6ee4d2d71d2208838aa44e09a61f2e62.tar.bz2 blog-8391d75b6ee4d2d71d2208838aa44e09a61f2e62.zip |
bsd-auth: add auth_approval definition
-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: --- |