diff options
author | davidn <davidn@FreeBSD.org> | 1997-01-07 16:28:12 +0000 |
---|---|---|
committer | davidn <davidn@FreeBSD.org> | 1997-01-07 16:28:12 +0000 |
commit | 4dfbc233a2bd38ba2bbaf687fa8bbc27d8b09782 (patch) | |
tree | 0631dd52c38162bfb8b48633a06e891d22505ec0 | |
parent | 544beb570510a6d942afca887af9919b5c83a248 (diff) | |
download | FreeBSD-src-4dfbc233a2bd38ba2bbaf687fa8bbc27d8b09782.zip FreeBSD-src-4dfbc233a2bd38ba2bbaf687fa8bbc27d8b09782.tar.gz |
Various bugfixes.
-rw-r--r-- | lib/libutil/login_cap.c | 18 | ||||
-rw-r--r-- | lib/libutil/login_class.c | 58 |
2 files changed, 42 insertions, 34 deletions
diff --git a/lib/libutil/login_cap.c b/lib/libutil/login_cap.c index b4566cc..961f539 100644 --- a/lib/libutil/login_cap.c +++ b/lib/libutil/login_cap.c @@ -21,7 +21,7 @@ * * Low-level routines relating to the user capabilities database * - * $Id: login_cap.c,v 1.2 1997/01/07 13:29:21 davidn Exp $ + * $Id: login_cap.c,v 1.3 1997/01/07 13:32:04 davidn Exp $ */ #include <stdio.h> @@ -56,8 +56,8 @@ allocstr(char * str) char * p; size_t sz = strlen(str) + 1; /* realloc() only if necessary */ if (sz <= internal_stringsz) - p = internal_string; - else if ((p = realloc(internal_string, sz)) != NULL) { + p = strcpy(internal_string, str); + else if ((p = realloc(internal_string, sz)) != NULL) { internal_stringsz = sz; internal_string = strcpy(p, str); } @@ -95,7 +95,9 @@ arrayize(char *str, const char *chars, int *size) for (i = 0, ptr = str; *ptr; i++) { int count = strcspn(ptr, chars); - ptr = ptr + count + 1; + ptr += count; + if (*ptr) + ++ptr; } if ((ptr = allocstr(str)) == NULL) { @@ -215,7 +217,7 @@ login_cap_t * login_getclass(const struct passwd *pwd) { const char * class = NULL; - if (pwd == NULL) { + if (pwd != NULL) { if ((class = pwd->pw_class) == NULL || *class == '\0') class = (pwd->pw_uid == 0) ? "root" : NULL; } @@ -301,11 +303,13 @@ login_getcaplist(login_cap_t *lc, const char * cap, const char * chars) char * login_getpath(login_cap_t *lc, const char *cap, char * error) { - char *ptr, *str = login_getcapstr(lc, (char*)cap, NULL, NULL); + char *str = login_getcapstr(lc, (char*)cap, NULL, NULL); - if (str == NULL || (ptr = allocstr(str)) == NULL) + if (str == NULL) str = error; else { + char *ptr = str; + while (*ptr) { int count = strcspn(ptr, ", \t"); ptr += count; diff --git a/lib/libutil/login_class.c b/lib/libutil/login_class.c index 1dc6cc4..1abe13d 100644 --- a/lib/libutil/login_class.c +++ b/lib/libutil/login_class.c @@ -21,7 +21,7 @@ * * High-level routines relating to use of the user capabilities database * - * $Id$ + * $Id: login_class.c,v 1.1 1997/01/04 16:50:06 davidn Exp $ */ #include <stdio.h> @@ -67,6 +67,9 @@ setclassresources(login_cap_t *lc) { struct login_res *lr = resources; + if (lc == NULL) + return; + while (lr->what != NULL) { struct rlimit rlim, newlim; @@ -166,16 +169,17 @@ substvar(char * var, const struct passwd * pwd, int hlen, int pch, int nlen) int l = strlen(p); if (p > var && *(p-1) == '\\') /* Escaped: */ - memmove(p - 1, p, l + 1); /* Slide-out the backslash */ + memmove(p - 1, p, l + 1); /* Slide-out the backslash */ else if (*p == '~') { - memmove(p + 1, p + hlen + pch, l); /* Subst homedir */ + int v = pch && *(p+1) != '/'; /* Avoid double // */ + memmove(p + hlen + v, p + 1, l); /* Subst homedir */ memmove(p, pwd->pw_dir, hlen); - if (pch) + if (v) p[hlen] = '/'; - p += hlen + pch; + p += hlen + v; } else /* if (*p == '$') */ { - memmove(p + 1, p + nlen, l); /* Subst username */ + memmove(p + nlen, p + 1, l); /* Subst username */ memmove(p, pwd->pw_name, nlen); p += nlen; } @@ -200,7 +204,7 @@ setclassenvironment(login_cap_t *lc, const struct passwd * pwd, int paths) while (vars->tag != NULL) { char * var = paths ? login_getpath(lc, vars->tag, NULL) - : login_getcapstr(lc, vars->tag, NULL, NULL); + : login_getcapstr(lc, vars->tag, NULL, NULL); char * np = substvar(var, pwd, hlen, pch, nlen); @@ -219,13 +223,16 @@ setclassenvironment(login_cap_t *lc, const struct passwd * pwd, int paths) */ if (!paths) { char ** set_env = login_getcaplist(lc, "setenv", ","); + if (set_env != NULL) { while (*set_env != NULL) { char *p = strchr(*set_env, '='); - if (p != NULL) { - char * np = substvar(set_env[1], pwd, hlen, pch, nlen); - if (np != NULL) { - setenv(set_env[0], np, 1); + if (p != NULL) { /* Discard invalid entries */ + char * np; + + *p++ = '\0'; + if ((np = substvar(p, pwd, hlen, pch, nlen)) != NULL) { + setenv(*set_env, np, 1); free(np); } } @@ -233,7 +240,6 @@ setclassenvironment(login_cap_t *lc, const struct passwd * pwd, int paths) } } } - } @@ -282,10 +288,8 @@ setusercontext(login_cap_t *lc, const struct passwd *pwd, uid_t uid, unsigned in if (lc == NULL) { - if (pwd == NULL || (lc = login_getclass(pwd)) == NULL) { - return -1; - } - llc = lc; /* free this when we're done */ + if (pwd != NULL && (lc = login_getclass(pwd)) != NULL) + llc = lc; /* free this when we're done */ } if (flags & LOGIN_SETPATH) @@ -313,14 +317,13 @@ setusercontext(login_cap_t *lc, const struct passwd *pwd, uid_t uid, unsigned in if ((flags & LOGIN_SETLOGIN) && setlogin(pwd->pw_name) != 0) { syslog(LOG_ERR, "setlogin '%s': %m", pwd->pw_name); login_close(llc); - return -1; /* You can't be too paranoid */ + return -1; } /* * Setup the user's group permissions */ if (flags & LOGIN_SETGROUP) { - /* XXX is it really a good idea to let errors here go? */ if (setgid(pwd->pw_gid) != 0) syslog(LOG_WARNING, "setgid %ld: %m", (long)pwd->pw_gid); if (initgroups(pwd->pw_name, pwd->pw_gid) == -1) @@ -328,15 +331,6 @@ setusercontext(login_cap_t *lc, const struct passwd *pwd, uid_t uid, unsigned in } /* - * This needs to be done after all of the above. - */ - if ((flags & LOGIN_SETUSER) && setuid(uid) != 0) { - syslog(LOG_ERR, "setuid %ld: %m", uid); - login_close(llc); - return -1; /* Paranoia again */ - } - - /* * FreeBSD extension: here we (might) loop and do this twice. * First, for the class we have been given, and next for * any user overrides in ~/.login.conf the user's home directory. @@ -366,6 +360,16 @@ setusercontext(login_cap_t *lc, const struct passwd *pwd, uid_t uid, unsigned in login_close(lc); /* User's private 'me' class */ login_close(llc); /* Class we opened */ + /* + * This needs to be done after all of the above. + * Do it last so we avoid getting killed and dropping core + */ + if ((flags & LOGIN_SETUSER) && setuid(uid) != 0) { + syslog(LOG_ERR, "setuid %ld: %m", uid); + login_close(llc); + return -1; /* Paranoia again */ + } + return 0; } |