summaryrefslogtreecommitdiff
path: root/acls.c
diff options
context:
space:
mode:
Diffstat (limited to 'acls.c')
-rw-r--r--acls.c327
1 files changed, 284 insertions, 43 deletions
diff --git a/acls.c b/acls.c
index 1157af5..74378d1 100644
--- a/acls.c
+++ b/acls.c
@@ -26,6 +26,24 @@ RCS_ID("$Id: acls.c,v 1.12 1994/05/31 12:31:21 mlschroe Exp $ FAU")
#include <sys/types.h>
#include "config.h"
+
+
+/* XXX: WHY IS THIS HERE?? :XXX */
+
+#ifdef CHECKLOGIN
+# ifdef _SEQUENT_
+# include <stdio.h> /* needed by <pwd.h> */
+# endif /* _SEQUENT_ */
+# include <pwd.h>
+# ifdef SHADOWPW
+# include <shadow.h>
+# endif /* SHADOWPW */
+#endif /* CHECKLOGIN */
+
+#ifndef NOSYSLOG
+# include <syslog.h>
+#endif
+
#include "screen.h" /* includes acls.h */
#include "extern.h"
@@ -37,6 +55,7 @@ RCS_ID("$Id: acls.c,v 1.12 1994/05/31 12:31:21 mlschroe Exp $ FAU")
extern struct comm comms[];
extern struct win *windows, *wtab[];
extern char NullStr[];
+extern char SockPath[];
extern struct display *display, *displays;
struct user *users;
@@ -52,9 +71,9 @@ static AclBits userbits;
*/
static char default_w_bit[ACL_BITS_PER_WIN] =
{
- 0, /* EXEC */
- 0, /* WRITE */
- 0 /* READ */
+ 1, /* EXEC */
+ 1, /* WRITE */
+ 1 /* READ */
};
static char default_c_bit[ACL_BITS_PER_CMD] =
@@ -70,7 +89,11 @@ static char default_c_bit[ACL_BITS_PER_CMD] =
*/
static int GrowBitfield __P((AclBits *, int, int, int));
-
+static struct usergroup **FindGroupPtr __P((struct usergroup **, struct user *, int));
+static int AclSetPermCmd __P((struct user *, char *, struct comm *));
+static int AclSetPermWin __P((struct user *, struct user *, char *, struct win *));
+static int UserAcl __P((struct user *, struct user **, int, char **));
+static int UserAclCopy __P((struct user **, struct user **));
static int
@@ -160,6 +183,8 @@ struct user **up;
(*up)->u_password = SaveStr(pass);
if (!(*up)->u_password)
(*up)->u_password = NullStr;
+ (*up)->u_detachwin = -1;
+ (*up)->u_detachotherwin = -1;
#ifdef MULTIUSER
(*up)->u_group = NULL;
@@ -275,6 +300,25 @@ struct user **up;
return 0;
}
+#if 0
+/* change user's password */
+int
+UserSetPass(name, pass, up)
+char *name, *pass;
+struct user **up;
+{
+ if (!up)
+ up = FindUserPtr(name);
+ if (!*up)
+ return UserAdd(name, pass, up);
+ if (!strcmp(name, "nobody")) /* he remains without password */
+ return -1;
+ strncpy((*up)->u_password, pass ? pass : "", 20);
+ (*up)->u_password[20] = '\0';
+ return 0;
+}
+#endif
+
/*
* Remove a user from the list.
* Destroy all his permissions and completely detach him from the session.
@@ -360,20 +404,16 @@ UserFreeCopyBuffer(u)
struct user *u;
{
struct win *w;
+ struct paster *pa;
if (!u->u_copybuffer)
return 1;
for (w = windows; w; w = w->w_next)
{
- if (w->w_pasteptr >= u->u_copybuffer &&
- w->w_pasteptr - u->u_copybuffer < u->u_copylen)
- {
- if (w->w_pastebuf)
- free((char *)w->w_pastebuf);
- w->w_pastebuf = 0;
- w->w_pasteptr = 0;
- w->w_pastelen = 0;
- }
+ pa = &w->w_paster;
+ if (pa->pa_pasteptr >= u->u_copybuffer &&
+ pa->pa_pasteptr - u->u_copybuffer < u->u_copylen)
+ FreePaster(pa);
}
free((char *)u->u_copybuffer);
u->u_copylen = 0;
@@ -382,6 +422,171 @@ struct user *u;
}
#endif /* COPY_PASTE */
+#ifdef MULTIUSER
+/*
+ * Traverses group nodes. It searches for a node that references user u.
+ * If recursive is true, nodes found in the users are also searched using
+ * depth first method. If none of the nodes references u, the address of
+ * the last next pointer is returned. This address will contain NULL.
+ */
+static struct usergroup **
+FindGroupPtr(gp, u, recursive)
+struct usergroup **gp;
+struct user *u;
+int recursive;
+{
+ struct usergroup **g;
+
+ ASSERT(recursive < 1000); /* Ouch, cycle detection failed */
+ while (*gp)
+ {
+ if ((*gp)->u == u)
+ return gp; /* found him here. */
+ if (recursive &&
+ *(g = FindGroupPtr(&(*gp)->u->u_group, u, recursive + 1)))
+ return g; /* found him there. */
+ gp = &(*gp)->next;
+ }
+ return gp; /* *gp is NULL */
+}
+
+/*
+ * Returns nonzero if failed or already linked.
+ * Both users are created on demand.
+ * Cyclic links are prevented.
+ */
+int
+AclLinkUser(from, to)
+char *from, *to;
+{
+ struct user **u1, **u2;
+ struct usergroup **g;
+
+ if (!*(u1 = FindUserPtr(from)) && UserAdd(from, NULL, u1))
+ return -1;
+ if (!*(u2 = FindUserPtr(to)) && UserAdd(to, NULL, u2))
+ return -1; /* hmm, could not find both users. */
+
+ if (*FindGroupPtr(&(*u2)->u_group, *u1, 1))
+ return 1; /* cyclic link detected! */
+ if (*(g = FindGroupPtr(&(*u1)->u_group, *u2, 0)))
+ return 2; /* aha, we are already linked! */
+
+ if (!(*g = (struct usergroup *)malloc(sizeof(struct usergroup))))
+ return -1; /* Could not alloc link. Poor screen */
+ (*g)->u = (*u2);
+ (*g)->next = NULL;
+ return 0;
+}
+
+/*
+ * The user pointer stored at *up will be substituted by a pointer
+ * to the named user's structure, if passwords match.
+ * returns NULL if successfull, an static error string otherwise
+ */
+char *
+DoSu(up, name, pw1, pw2)
+struct user **up;
+char *name, *pw1, *pw2;
+{
+ struct user *u;
+ int sorry = 0;
+
+ if (!(u = *FindUserPtr(name)))
+ sorry++;
+ else
+ {
+#ifdef CHECKLOGIN
+ struct passwd *pp;
+#ifdef SHADOWPW
+ struct spwd *ss;
+ int t, c;
+#endif
+ char *pass = "";
+
+ if (!(pp = getpwnam(name)))
+ {
+ debug1("getpwnam(\"%s\") failed\n", name);
+ if (!(pw1 && *pw1 && *pw1 != '\377'))
+ {
+ debug("no unix account, no screen passwd\n");
+ sorry++;
+ }
+ }
+ else
+ pass = pp->pw_passwd;
+#ifdef SHADOWPW
+ for (t = 0; t < 13; t++)
+ {
+ c = pass[t];
+ if (!(c == '.' || c == '/' ||
+ (c >= '0' && c <= '9') ||
+ (c >= 'a' && c <= 'z') ||
+ (c >= 'A' && c <= 'Z')))
+ break;
+ }
+ if (t < 13)
+ {
+ if (!(ss = getspnam(name)))
+ {
+ debug1("getspnam(\"%s\") failed\n", name);
+ sorry++;
+ }
+ else
+ pass = ss->sp_pwdp;
+ }
+#endif /* SHADOWPW */
+
+ if (pw2 && *pw2 && *pw2 != '\377') /* provided a system password */
+ {
+ if (!*pass || /* but needed none */
+ strcmp(crypt(pw2, pass), pass))
+ {
+ debug("System password mismatch\n");
+ sorry++;
+ }
+ }
+ else /* no pasword provided */
+ if (*pass) /* but need one */
+ sorry++;
+#endif
+ if (pw1 && *pw1 && *pw1 != '\377') /* provided a screen password */
+ {
+ if (!*u->u_password || /* but needed none */
+ strcmp(crypt(pw1, u->u_password), u->u_password))
+ {
+ debug("screen password mismatch\n");
+ sorry++;
+ }
+ }
+ else /* no pasword provided */
+ if (*u->u_password) /* but need one */
+ sorry++;
+ }
+
+ debug2("syslog(LOG_NOTICE, \"screen %s: \"su %s\" ", SockPath, name);
+ debug2("%s for \"%s\"\n", sorry ? "failed" : "succeded", (*up)->u_name);
+#ifndef NOSYSLOG
+# ifdef BSD_42
+ openlog("screen", LOG_PID);
+# else
+ openlog("screen", LOG_PID, LOG_AUTH);
+# endif /* BSD_42 */
+ syslog(LOG_NOTICE, "%s: \"su %s\" %s for \"%s\"", SockPath, name,
+ sorry ? "failed" : "succeded", (*up)->u_name);
+ closelog();
+#else
+ debug("NOT LOGGED.\n");
+#endif /* NOSYSLOG */
+
+ if (sorry)
+ return "Sorry.";
+ else
+ *up = u; /* substitute user now */
+ return NULL;
+}
+#endif /* MULTIUSER */
+
/************************************************************************
* end of user managing code *
************************************************************************/
@@ -411,6 +616,8 @@ struct user *u;
{
while (--j >= 0)
free((char *)w->w_userbits[j]);
+ free((char *)w->w_mon_notify);
+ free((char *)w->w_lio_notify);
return -1;
}
for (i = 0; i < maxusercount; i++)
@@ -421,6 +628,19 @@ struct user *u;
return 0;
}
+void
+FreeWindowAcl(w)
+struct win *w;
+{
+ int i;
+
+ for (i = 0; i < ACL_BITS_PER_WIN; i++)
+ free((char *)w->w_userbits[i]);
+ free((char *)w->w_mon_notify);
+ free((char *)w->w_lio_notify);
+}
+
+
/* if mode starts with '-' we remove the users exec bit for cmd */
/*
* NOTE: before you make this function look the same as
@@ -593,7 +813,7 @@ char *mode, *s;
AclSetPermWin(uu, u, mode, (struct win *)1);
else /* .. or all windows */
for (w = windows; w; w = w->w_next)
- AclSetPermWin(NULL, u, mode, w);
+ AclSetPermWin((struct user *)0, u, mode, w);
s++;
break;
case '?':
@@ -612,7 +832,7 @@ char *mode, *s;
if ((i = FindCommnr(s)) != RC_ILLEGAL)
AclSetPermCmd(u, mode, &comms[i]);
else if (((i = WindowByNoN(s)) >= 0) && wtab[i])
- AclSetPermWin(NULL, u, mode, wtab[i]);
+ AclSetPermWin((struct user *)0, u, mode, wtab[i]);
else
/* checking group name */
return -1;
@@ -774,44 +994,65 @@ char **argv;
return 0;
}
-#if 0
-void
-AclWinSwap(a, b)
-int a, b;
+/*
+ * Preprocess argments, so that umask can be set with UsersAcl
+ *
+ * all current users umask ±rwxn
+ * one specific user umask user1±rwxn
+ * several users umask user1,user2,...±rwxn
+ * default_w_bits umask ?±rwxn
+ * default_c_bits umask ??±rwxn
+ */
+int
+AclUmask(u, str, errp)
+struct user *u;
+char *str;
+char **errp;
{
- int a_bit = 0, b_bit = 0;
- AclGroupList **g;
- AclBits p;
+ char mode[16];
+ char *av[3];
+ char *p, c = '\0';
- debug2("acl lists swapping windows %d and %d\n", a, b);
-
- for (g = &aclgrouproot; *g; g = &(*g)->next)
+ /* split str into user and bits section. */
+ for (p = str; *p; p++)
+ if ((c = *p) == '+' || c == '-')
+ break;
+ if (!*p)
+ {
+ *errp = "Bad argument. Should be ``[user[,user...]{+|-}rwxn''.";
+ return -1;
+ }
+ strncpy(mode, p, 15);
+ mode[15] = '\0';
+ *p = '\0';
+
+ /* construct argument vector */
+ if (!strcmp("??", str))
+ {
+ str++;
+ av[2] = "?";
+ }
+ else
+ av[2] = "#";
+ av[1] = mode;
+ av[0] = *str ? str : "*";
+ /* call UsersAcl */
+ if (UsersAcl(u, 3, av))
{
- p = (*g)->group->winbits;
- /* see if there was a bit for window a. zap it */
- if (a >= 0)
- if ((a_bit = ACLBIT(a) & ACLBYTE(p, a)))
- ACLBYTE(p, a) &= ~ACLBIT(a);
- /* see if there was a bit for window b. zap it */
- if (b >= 0)
- if ((b_bit = ACLBIT(b) & ACLBYTE(p, b)))
- ACLBYTE(p, b) &= ~ACLBIT(b);
- /* b may cause a set */
- if (b_bit && a >= 0)
- ACLBYTE(p, a) |= ACLBIT(a);
- /* a may cause b set */
- if (a_bit && b >= 0)
- ACLBYTE(p, b) |= ACLBIT(b);
+ *errp = "UsersAcl failed. Hmmm.";
+ *p = c;
+ return -1;
}
+ *p = c;
+ return 0;
}
-#else
+
void
AclWinSwap(a, b)
int a, b;
{
- debug2("AclWinSwap(%d, %d) DUMMY\n", a, b);
+ debug2("AclWinSwap(%d, %d) NOP.\n", a, b);
}
-#endif
struct user *EffectiveAclUser = NULL; /* hook for AT command permission */