summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDante Catalfamo2021-05-29 21:08:18 -0400
committerDante Catalfamo2021-05-29 21:08:18 -0400
commit8391d75b6ee4d2d71d2208838aa44e09a61f2e62 (patch)
tree5eab76b0178234edc5f71652ec4e0d40aa7528c7
parentb868ffba6a72f3cb626fcac9692d261a022452dd (diff)
downloadblog-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.org149
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:
---