Пример #1
0
int
iaccess(File *f, Dentry *d, int m)
{
	if(wstatallow)
		return 0;

	/*
	 * owner is next
	 */
	if(f->uid == d->uid)
		if((m<<6) & d->mode)
			return 0;
	/*
	 * group membership is hard
	 */
	if(ingroup(f->uid, d->gid))
		if((m<<3) & d->mode)
			return 0;
	/*
	 * other access for everyone except members of group 9999
	 */
	if(m & d->mode){
		/* 
		 *  walk directories regardless.
		 *  otherwise its impossible to get
		 *  from the root to noworld's directories.
		 */
		if((d->mode & DDIR) && (m == DEXEC))
			return 0;
		if(!ingroup(f->uid, 9999))
			return 0;
	}
	return 1;
}
Пример #2
0
int
main(int argc, char **argv)
{
	struct cmd *c;

	effective_uid = geteuid();
	real_uid = getuid();
	effective_gid = getegid();
	real_gid = getgid();
	PRIV_END;	/* be safe */

	openlog("lpc", 0, LOG_LPR);
	if (--argc > 0) {
		c = getcmd(*++argv);
		if (c == (struct cmd *)-1) {
			printf("?Ambiguous command\n");
			exit(1);
		}
		if (c == 0) {
			printf("?Invalid command\n");
			exit(1);
		}
		if (c->c_priv && real_uid && ingroup(LPR_OPER) == 0) {
			printf("?Privileged command\n");
			exit(1);
		}
		(*c->c_handler)(argc, argv);
		exit(0);
	}
	fromatty = isatty(fileno(stdin));
	signal(SIGINT, intr);
	for (;;)
		cmdscanner();
}
Пример #3
0
Файл: sub.c Проект: npe9/harvey
int
iaccess(File *f, Dentry *d, int m)
{
	/* uid none gets only other permissions */
	if(f->uid != 0) {
		/*
		 * owner
		 */
		if(f->uid == d->uid)
			if((m<<6) & d->mode)
				return 0;
		/*
		 * group membership
		 */
		if(ingroup(f->uid, d->gid))
			if((m<<3) & d->mode)
				return 0;
	}

	/*
	 * other
	 */
	if(m & d->mode) {
		if((d->mode & DDIR) && (m == DEXEC))
			return 0;
		if(!ingroup(f->uid, 9999))
			return 0;
	}

	/*
	 * various forms of superuser
	 */
	if(wstatallow)
		return 0;
	if(duallow != 0 && duallow == f->uid)
		if((d->mode & DDIR) && (m == DREAD || m == DEXEC))
			return 0;

	return 1;
}
Пример #4
0
/*
 * Command parser.
 */
static void
cmdscanner(void)
{
	struct cmd *c;

	for (;;) {
		if (gotintr) {
			putchar('\n');
			gotintr = 0;
		}
		if (fromatty) {
			printf("lpc> ");
			fflush(stdout);
		}

		siginterrupt(SIGINT, 1);
		if (fgets(cmdline, MAX_CMDLINE, stdin) == NULL) {
			if (errno == EINTR && gotintr) {
				siginterrupt(SIGINT, 0);
				return;
			}
			siginterrupt(SIGINT, 0);
			quit(0, NULL);
		}
		siginterrupt(SIGINT, 0);

		makeargv();
		if (margc == 0)
			break;
		c = getcmd(margv[0]);
		if (c == (struct cmd *)-1) {
			printf("?Ambiguous command\n");
			continue;
		}
		if (c == 0) {
			printf("?Invalid command\n");
			continue;
		}
		if (c->c_priv && getuid() && ingroup(LPR_OPER) == 0) {
			printf("?Privileged command\n");
			continue;
		}
		(*c->c_handler)(margc, margv);
	}
}
Пример #5
0
/*
 * Delete logins according to the criteria given in options.
 */
void
userdel(void)
{
	struct login *lp, *lprev = NULL;

	if (dflag == 0 && pflag == 0 && selgrp == NULL)
		return;
	for (lp = l0; lp; lp = lp->l_next)
		if (pflag && (lp->l_pwdp == NULL || *lp->l_pwdp != '\0')
				|| selgrp && !ingroup(lp)
				|| dflag && !duplicate(lp)) {
			if (lprev != NULL)
				lprev->l_next = lp->l_next;
			else
				l0 = lp->l_next;
		} else
			lprev = lp;
}
Пример #6
0
int
main(int argc, char *argv[])
{
	register struct cmd *c;

	euid = geteuid();
	uid = getuid();
	PRIV_END
	progname = argv[0];
	openlog("lpd", 0, LOG_LPR);

	if (--argc > 0) {
		c = getcmd(*++argv);
		if (c == (struct cmd *)-1) {
			printf("?Ambiguous command\n");
			exit(1);
		}
		if (c == NULL) {
			printf("?Invalid command\n");
			exit(1);
		}
		if ((c->c_opts & LPC_PRIVCMD) && getuid() &&
		    ingroup(LPR_OPER) == 0) {
			printf("?Privileged command\n");
			exit(1);
		}
		if (c->c_generic != NULL)
			generic(c->c_generic, c->c_opts, c->c_handler,
			    argc, argv);
		else
			(*c->c_handler)(argc, argv);
		exit(0);
	}
	fromatty = isatty(fileno(stdin));
	if (!fromatty)
		signal(SIGINT, intr);
	for (;;) {
		cmdscanner();
	}
}
Пример #7
0
int
isevegroup(void)
{
	return ingroup(up->user, eve);
}
Пример #8
0
/*
 * Command parser.
 */
static void
cmdscanner(void)
{
	register struct cmd *c;
	static EditLine *el;
	static History *hist;
	HistEvent he;
	size_t len;
	int num;
	const char *bp;

	num = 0;
	bp = NULL;
	el = NULL;
	hist = NULL;
	for (;;) {
		if (fromatty) {
			if (!el) {
				el = el_init("lpc", stdin, stdout, stderr);
				hist = history_init();
				history(hist, &he, H_SETSIZE, 100);
				el_set(el, EL_HIST, history, hist);
				el_set(el, EL_EDITOR, "emacs");
				el_set(el, EL_PROMPT, lpc_prompt);
				el_set(el, EL_SIGNAL, 1);
				el_source(el, NULL);
				/*
				 * EditLine init may call 'cgetset()' to set a
				 * capability-db meant for termcap (eg: to set
				 * terminal type 'xterm').  Reset that now, or
				 * that same db-information will be used for
				 * printcap (giving us an "xterm" printer, with
				 * all kinds of invalid capabilities...).
				 */
				cgetset(NULL);
			}
			if ((bp = el_gets(el, &num)) == NULL || num == 0)
				quit(0, NULL);

			len = (num > MAX_CMDLINE - 1) ? MAX_CMDLINE - 1 : num;
			memcpy(cmdline, bp, len);
			cmdline[len] = 0; 
			history(hist, &he, H_ENTER, bp);

		} else {
			if (fgets(cmdline, MAX_CMDLINE, stdin) == NULL)
				quit(0, NULL);
			if (cmdline[0] == 0 || cmdline[0] == '\n')
				break;
		}

		makeargv();
		if (margc == 0)
			continue;
		if (el != NULL && el_parse(el, margc, margv) != -1)
			continue;

		c = getcmd(margv[0]);
		if (c == (struct cmd *)-1) {
			printf("?Ambiguous command\n");
			continue;
		}
		if (c == NULL) {
			printf("?Invalid command\n");
			continue;
		}
		if ((c->c_opts & LPC_PRIVCMD) && getuid() &&
		    ingroup(LPR_OPER) == 0) {
			printf("?Privileged command\n");
			continue;
		}

		/*
		 * Two different commands might have the same generic rtn
		 * (eg: "clean" and "tclean"), and just use different
		 * handler routines for distinct command-setup.  The handler
		 * routine might also be set on a generic routine for
		 * initial parameter processing.
		 */
		if (c->c_generic != NULL)
			generic(c->c_generic, c->c_opts, c->c_handler,
			    margc, margv);
		else
			(*c->c_handler)(margc, margv);
	}
}
Пример #9
0
/* -------------------------------------------------------------------- */
void renamegroup(void)
{
    label groupname, newname;
    char desc[80];
    int groupslot, locked, hidden, autoAdd;

    getString("group", groupname, NAMESIZE, FALSE, ECHO, "");

    groupslot = partialgroup(groupname);

    if ( grpBuf.group[groupslot].hidden && !ingroup(groupslot) && !onConsole)
        groupslot = ERROR;

    if ( groupslot == ERROR || !strlen(groupname) )
    {
        mPrintf("\n No such group.");
        return;
    }

    doCR();
    mPrintf(" Group: %s ", grpBuf.group[groupslot].groupname);
    if (grpBuf.group[groupslot].lockout)
    {
        mPrintf("(Locked) ");
    }
    if (grpBuf.group[groupslot].hidden)
    {
        mPrintf("(Hidden) ");
    }
    if (grpBuf.group[groupslot].autoAdd)
    {
        mPrintf("(Auto-Add)");
    }
    doCR();
    mPrintf(" Descibed: %s ", grpBuf.group[groupslot].desc);
    doCR();
    
    getString("new group name", newname, NAMESIZE, FALSE, ECHO, 
              grpBuf.group[groupslot].groupname);
    
    getString("new group description", desc, 79, FALSE, ECHO, "");
    
    if (groupexists(newname) != ERROR 
     && stricmp(newname, grpBuf.group[groupslot].groupname) != SAMESTRING)
    {
        mPrintf("\n A \'%s\' group already exists.", newname);
        return;
    }

    /*  locked group? */
    locked =
        (getYesNo("Lock group from aides", 
                  (char)grpBuf.group[groupslot].lockout ));

    hidden =
        (getYesNo("Make group hidden", (char)grpBuf.group[groupslot].hidden ));
    
    if (groupslot)
    {
        autoAdd =
        (getYesNo("Make group auto-add", 
                 (char)grpBuf.group[groupslot].autoAdd));
    }

    if (getYesNo(confirm, 0))
    {
        grpBuf.group[groupslot].lockout = locked;
        grpBuf.group[groupslot].hidden  = hidden;
        grpBuf.group[groupslot].autoAdd = autoAdd;
        
        strcpy(grpBuf.group[groupslot].groupname, newname);
        
        if (*desc)
        {
            strcpy(grpBuf.group[groupslot].desc, desc);
        }
        
        sprintf(msgBuf->mbtext,
        "Group %s renamed %s", groupname, newname);
    
        trap(msgBuf->mbtext, T_SYSOP);
    
        putGroup();
    }
}
Пример #10
0
/* -------------------------------------------------------------------- */
void listgroup(void)
{
    label groupname;
    int i, groupslot;

    getString("", groupname, NAMESIZE, FALSE, ECHO, "");

    outFlag = OUTOK;

    if ( !strlen(groupname))
    {
        for (i = 0; i < MAXGROUPS; i++)
        {
            /* can they see the group */
            if (  grpBuf.group[i].g_inuse
              && (!grpBuf.group[i].lockout || sysop)
              && (!grpBuf.group[i].hidden  || onConsole || ingroup(i))
              )
            {
                mPrintf(" %-30s %c%c%c ", 
                        grpBuf.group[i].groupname,
                        grpBuf.group[i].lockout ? 'L' : ' ',
                        grpBuf.group[i].hidden  ? 'H' : ' ',
                        (grpBuf.group[i].autoAdd  || !i)
                                                ? 'A' : ' '
                        );
                mPrintf("%s", grpBuf.group[i].desc);
                doCR();
            }
        }  
        return;
    }

    groupslot = partialgroup(groupname);

    if ( grpBuf.group[groupslot].hidden && !ingroup(groupslot) )
        groupslot = ERROR;

    if (groupslot == ERROR)
    {
        mPrintf("\n No such group.");
        return;
    }

    if ( grpBuf.group[groupslot].lockout
    && (!(logBuf.lbflags.SYSOP || onConsole)) )
    {
        mPrintf("\n Group is locked.");
        return;
    }

    doCR();

    outFlag = OUTOK;

    mPrintf(" Users:"); doCR();
    
    prtList(LIST_START);

    for (i = 0; ( ( i < cfg.MAXLOGTAB) && (outFlag != OUTSKIP)
        && (outFlag != OUTNEXT) ); i++)
    {
        if (logTab[i].ltpwhash != 0 && logTab[i].ltnmhash != 0)
        {
            getLog(&lBuf, logTab[i].ltlogSlot);

            if (lBuf.groups[groupslot] == grpBuf.group[groupslot].groupgen)
            {
                prtList(lBuf.lbname);
                
                /* doCR();
                mPrintf(" %s", lBuf.lbname); */
            }
            else
            {
                mAbort(FALSE);
            }
        }
        
        if (outFlag == OUTSKIP)
        {
            doCR();
            return;
        }  
    }
    
    prtList(LIST_END);
    
    if (outFlag == OUTSKIP)
    {
        doCR();
        return;
    }  

    outFlag = OUTOK;

    doCR(); 

    mPrintf(" Rooms:"); doCR();
    
    prtList(LIST_START);

    for (i = 0; ( ( i < MAXROOMS) && (outFlag != OUTSKIP)
        && (outFlag != OUTNEXT) ); i++)
    {
         if  (   roomTab[i].rtflags.INUSE 
             &&  roomTab[i].rtflags.GROUPONLY
             && (roomTab[i].grpno  == (unsigned char)groupslot)
         /*  && (roomTab[i].grpgen == grpBuf.group[groupslot].groupgen) */ )
         {
            prtList(roomTab[i].rtname);
         }
    }

    prtList(LIST_END);
    
    if (outFlag == OUTSKIP)
    {
        doCR();
        return;
    }  

    outFlag = OUTOK;

    doCR(); 

    mPrintf(" Hallways:"); 

    for (i = 0; ( ( i < MAXHALLS) && (outFlag != OUTSKIP)
        && (outFlag != OUTNEXT) ); i++)
    {
        if ( hallBuf->hall[i].h_inuse &&
             hallBuf->hall[i].owned   &&
            (hallBuf->hall[i].grpno == (unsigned char)groupslot) )
        {
            doCR();
            mPrintf(" %s", hallBuf->hall[i].hallname);
        }
    }
    doCR();
}
Пример #11
0
/* -------------------------------------------------------------------- */
void groupfunc(void)
{
    label               who;
    label groupname;
    int groupslot,      logNo;

    getString("group", groupname, NAMESIZE, FALSE, ECHO, "");

    groupslot = partialgroup(groupname);

    if (groupslot != ERROR)
    {
        if ( grpBuf.group[groupslot].lockout && !sysop )
            groupslot = ERROR;
    
        if(  grpBuf.group[groupslot].hidden 
          && !ingroup(groupslot) 
          && !onConsole 
          )
            groupslot = ERROR;
    }

    if ( groupslot == ERROR || !strlen(groupname) )
    {
        mPrintf("\n No such group.");
        return;
    }

    getNormStr("who", who, NAMESIZE, ECHO);
    logNo   = findPerson(who, &lBuf);
    if (logNo == ERROR || !strlen(who) )  
    {
        mPrintf("No \'%s\' known. \n ", who);
        return;
    }

    if (lBuf.groups[groupslot] == grpBuf.group[groupslot].groupgen)
    {
        if (getYesNo("Remove from group", 0))
        {
            lBuf.groups[groupslot] =
                (uchar)((grpBuf.group[groupslot].groupgen
              + (MAXGROUPGEN - 1)) % MAXGROUPGEN);

            sprintf(msgBuf->mbtext,
                    "%s kicked out of group %s by %s",
                    lBuf.lbname,
                    grpBuf.group[groupslot].groupname,
                    logBuf.lbname );

            trap(msgBuf->mbtext, T_AIDE);

            aideMessage();
        }
    }
    else

    if (getYesNo("Add to group", 0))
    {
        lBuf.groups[groupslot] = grpBuf.group[groupslot].groupgen;

        sprintf(msgBuf->mbtext,
        "%s added to group %s by %s",
        lBuf.lbname,
        grpBuf.group[groupslot].groupname,
        logBuf.lbname );

        trap(msgBuf->mbtext, T_AIDE);

        aideMessage();

    }

    putLog(&lBuf, logNo);

    /* see if it is us: */
    if (loggedIn  &&  strcmpi(logBuf.lbname, who) == SAMESTRING) 
    {
        logBuf.groups[groupslot] = lBuf.groups[groupslot];
    }

}
Пример #12
0
/* -------------------------------------------------------------------- */
void globaluser(void)
{
    label               who;
    int groupslot, yn, logNo;

    getNormStr("who", who, NAMESIZE, ECHO);
    logNo   = findPerson(who, &lBuf);
    if (logNo == ERROR || !strlen(who) )  
    {
        mPrintf("No \'%s\' known. \n ", who);
        return;
    }

    for(groupslot=0; groupslot < MAXGROUPS; groupslot++)
    {
      if (grpBuf.group[groupslot].g_inuse 
          && ( !grpBuf.group[groupslot].lockout || sysop )
          && ( !grpBuf.group[groupslot].hidden  || ingroup(groupslot) )
         )
      {
        mPrintf(" %s", grpBuf.group[groupslot].groupname);
        if (lBuf.groups[groupslot] == grpBuf.group[groupslot].groupgen)
        {
            if ((yn = getYesNo("Remove from group", 3)) != 0 /*NULL*/)
            {
                if (yn == 2)
                {
                    SaveAideMess();
                    return;
                }

                lBuf.groups[groupslot] =
                  (uchar)((grpBuf.group[groupslot].groupgen
                  + (MAXGROUPGEN - 1)) % MAXGROUPGEN);
                sprintf(msgBuf->mbtext,
                  "%s kicked out of group %s by %s",
                  lBuf.lbname,
                grpBuf.group[groupslot].groupname,
                  logBuf.lbname );

                trap(msgBuf->mbtext, T_AIDE);

              amPrintf(" %s\n", msgBuf->mbtext);
            }
        }
        else
        {
          if ((yn = getYesNo("Add to group", 3)) != /* NULL */ 0)
          {
            if (yn == 2)
                {
                    SaveAideMess();
                    return;
                }

            lBuf.groups[groupslot] = grpBuf.group[groupslot].groupgen;

            sprintf(msgBuf->mbtext,
              "%s added to group %s by %s",
              lBuf.lbname,
              grpBuf.group[groupslot].groupname,
              logBuf.lbname );
            trap(msgBuf->mbtext, T_SYSOP);

              amPrintf(" %s\n",msgBuf->mbtext);
          }
        }
        putLog(&lBuf, logNo);

        /* see if it is us: */
        if (loggedIn  &&  strcmpi(logBuf.lbname, who) == SAMESTRING) 
        {
            logBuf.groups[groupslot] = lBuf.groups[groupslot];
        }
      }
    }

    SaveAideMess();
}
Пример #13
0
/* -------------------------------------------------------------------- */
void globalgroup(void)
{
    label groupname;
    int groupslot, i, yn, add, logNo;

    mPrintf("(A/R/[B]): ");

    switch (toupper( iCharNE() ))
    {
    case 'A':
        mPrintf("Add\n ");
        add = 1;
        break;
    
    case 'R':
        mPrintf("Remove\n ");
        add = 2;
        break;
    
    case '?':
        tutorial("grpglob.mnu");
        return;
        
    case 'B':
    case 10:
    case 13:
    default:
        mPrintf("Both\n ");
        add = 0;
        break;
    }

    getString("group", groupname, NAMESIZE, FALSE, ECHO, "");

    groupslot = partialgroup(groupname);

    if ( grpBuf.group[groupslot].hidden && !ingroup(groupslot) )
        groupslot = ERROR;

    if ( groupslot == ERROR || !strlen(groupname) )
    {
        mPrintf("\n No such group.");
        return;
    }

    if ( grpBuf.group[groupslot].lockout && !sysop )
    {
        mPrintf("\n Group is locked.");
        return;
    }

    for (i = 0; i < cfg.MAXLOGTAB; i++)
    {
        if (logTab[i].ltpwhash != 0 && logTab[i].ltnmhash !=0)
        {
            logNo=logTab[i].ltlogSlot;
            getLog(&lBuf, logNo);
            
            /* Get out.. */
            outFlag = OUTOK;
            if (mAbort(FALSE)) break;
            outFlag = IMPERVIOUS;
            
            if (lBuf.groups[groupslot] == grpBuf.group[groupslot].groupgen)
            {
                if(add == 2 || add == 0)
                {
                    mPrintf(" 3%s0", lBuf.lbname);
                    yn=getYesNo("Remove from group", 0+3);
                    if (yn == 2)
                    {
                        SaveAideMess();
                        return;
                    }
      
                    if (yn)
                    {
                        lBuf.groups[groupslot] =
                            (uchar)((grpBuf.group[groupslot].groupgen
                          + (MAXGROUPGEN - 1)) % MAXGROUPGEN);
          
                        sprintf(msgBuf->mbtext,
                            "%s kicked out of group %s by %s",
                            lBuf.lbname,
                            grpBuf.group[groupslot].groupname,
                            logBuf.lbname );
           
                        trap(msgBuf->mbtext, T_SYSOP);
          
                        amPrintf(" %s\n", msgBuf->mbtext);
                    }
                }
            }
            else
            {
                if (add == 0 || add == 1)
                {
                    mPrintf(" 3%s0", lBuf.lbname);
                    yn=getYesNo("Add to group", 0+3);
                    if (yn == 2)
                    {
                        SaveAideMess();
                        return;
                    }
                    if (yn)
                    {
                        lBuf.groups[groupslot] =
                            grpBuf.group[groupslot].groupgen;
           
                        sprintf(msgBuf->mbtext,
                            "%s added to group %s by %s",
                            lBuf.lbname,
                            grpBuf.group[groupslot].groupname,
                            logBuf.lbname );
         
                        trap(msgBuf->mbtext, T_AIDE);
           
                        amPrintf(" %s\n",msgBuf->mbtext);
                    }
                }
            }
  
            putLog(&lBuf, logNo);
     
            /* see if it is us: */
            if (loggedIn  &&  strcmpi(logBuf.lbname, lBuf.lbname) == SAMESTRING)
            {
                logBuf.groups[groupslot] = lBuf.groups[groupslot];
            }
        }
    }

    SaveAideMess();
}
Пример #14
0
void negotiate(void)
{
    int   groupslot, i;
    int   firstime = TRUE;
    float priority = 0;

    clearthisAccount();

    for (groupslot = 0; groupslot < MAXGROUPS; groupslot++)
    {
        if (ingroup(groupslot)
            && accountBuf.group[groupslot].account.have_acc)
        {
            /* is in a group with accounting */
            thisAccount.have_acc = TRUE;

            if (accountBuf.group[groupslot].account.priority >= priority)
            {

                if (accountBuf.group[groupslot].account.priority > priority)
                {                       /********************************/
                    clearthisAccount(); /* if it's more imp, start over */
                    thisAccount.have_acc = TRUE;/*otherwise, compromise!*/
                    firstime = TRUE;                
                }                               /************************/

                priority = accountBuf.group[groupslot].account.priority;

                for ( i = 0; i < 7; ++i)
                    if (accountBuf.group[groupslot].account.days[i])
                        thisAccount.days[i] = 1;

                for ( i = 0; i < 24; ++i)
                {
                    if (accountBuf.group[groupslot].account.hours[i])
                        thisAccount.hours[i]   = 1;

                    if (accountBuf.group[groupslot].account.special[i])
                        thisAccount.special[i] = 1;
                }

                if  (accountBuf.group[groupslot].account.dayinc >
                        thisAccount.dayinc  || firstime)
                    thisAccount.dayinc
                        = accountBuf.group[groupslot].account.dayinc;

                if  (accountBuf.group[groupslot].account.sp_dayinc >
                    thisAccount.sp_dayinc  || firstime)
                    thisAccount.sp_dayinc =
                    accountBuf.group[groupslot].account.sp_dayinc;

                if  (accountBuf.group[groupslot].account.maxbal >
                    thisAccount.maxbal)
                    thisAccount.maxbal
                        = accountBuf.group[groupslot].account.maxbal;

    /* these are */ thisAccount.dlmult =
    /* special   */ accountBuf.group[groupslot].account.dlmult;
    /*           */
    /*           */ thisAccount.ulmult =
    /*-----------*/ accountBuf.group[groupslot].account.ulmult;

                firstime = FALSE;
            }  /*  if  */
        }  /*  if  */
    }  /*  for  */
}
Пример #15
0
int
doremove(File *f, int iscon)
{
	Iobuf *p, *p1;
	Dentry *d, *d1;
	int32_t addr;
	int slot, err;

	p = 0;
	p1 = 0;
	if(isro(f->fs->dev) || (f->cp != cons.chan && writegroup && !ingroup(f->uid, writegroup))) {
		err = Eronly;
		goto out;
	}
	/*
	 * check on parent directory of file to be deleted
	 */
	if(f->wpath == 0 || f->wpath->addr == f->addr) {
		err = Ephase;
		goto out;
	}
	p1 = getbuf(f->fs->dev, f->wpath->addr, Bread);
	d1 = getdir(p1, f->wpath->slot);
	if(!d1 || checktag(p1, Tdir, QPNONE) || !(d1->mode & DALLOC)) {
		err = Ephase;
		goto out;
	}
	if(!iscon && iaccess(f, d1, DWRITE)) {
		err = Eaccess;
		goto out;
	}
	accessdir(p1, d1, FWRITE);
	putbuf(p1);
	p1 = 0;

	/*
	 * check on file to be deleted
	 */
	p = getbuf(f->fs->dev, f->addr, Bread);
	d = getdir(p, f->slot);
	if(!d || checktag(p, Tdir, QPNONE) || !(d->mode & DALLOC)) {
		err = Ealloc;
		goto out;
	}
	if(err = mkqidcmp(&f->qid, d))
		goto out;

	/*
	 * if deleting a directory, make sure it is empty
	 */
	if((d->mode & DDIR))
	for(addr=0;; addr++) {
		p1 = dnodebuf(p, d, addr, 0);
		if(!p1)
			break;
		if(checktag(p1, Tdir, d->qid.path)) {
			err = Ephase;
			goto out;
		}
		for(slot=0; slot<DIRPERBUF; slot++) {
			d1 = getdir(p1, slot);
			if(!(d1->mode & DALLOC))
				continue;
			err = Eempty;
			goto out;
		}
		putbuf(p1);
	}

	/*
	 * do it
	 */
	dtrunc(p, d);
	memset(d, 0, sizeof(Dentry));
	settag(p, Tdir, QPNONE);

out:
	if(p1)
		putbuf(p1);
	if(p)
		putbuf(p);
	return err;
}
Пример #16
0
void
f_write(Chan *cp, Oldfcall *in, Oldfcall *ou)
{
	Iobuf *p, *p1;
	Dentry *d;
	File *f;
	Tlock *t;
	int32_t offset, addr, tim;
	int count, nwrite, o, n;

	if(CHAT(cp)) {
		print("c_write %d\n", cp->chan);
		print("	fid = %d\n", in->fid);
		print("	offset = %ld\n", in->offset);
		print("	count = %ld\n", in->count);
	}

	offset = in->offset;
	count = in->count;
	nwrite = 0;
	p = 0;
	f = filep(cp, in->fid, 0);
	if(!f) {
		ou->err = Efid;
		goto out;
	}
	if(!(f->open & FWRITE)) {
		ou->err = Eopen;
		goto out;
	}
	if(isro(f->fs->dev) || (cp != cons.chan && writegroup && !ingroup(f->uid, writegroup))) {
		ou->err = Eronly;
		goto out;
	}
	if(count < 0 || count > MAXDAT) {
		ou->err = Ecount;
		goto out;
	}
	if(offset < 0) {
		ou->err = Eoffset;
		goto out;
	}
	p = getbuf(f->fs->dev, f->addr, Bread|Bmod);
	d = getdir(p, f->slot);
	if(!d || !(d->mode & DALLOC)) {
		ou->err = Ealloc;
		goto out;
	}
	if(ou->err = mkqidcmp(&f->qid, d))
		goto out;
	if(t = f->tlock) {
		tim = time(0);
		if(t->time < tim || t->file != f) {
			ou->err = Ebroken;
			goto out;
		}
		/* renew the lock */
		t->time = tim + TLOCK;
	}
	accessdir(p, d, FWRITE);
	if(d->mode & DAPND)
		offset = d->size;
	if(offset+count > d->size)
		d->size = offset+count;
	while(count > 0) {
		addr = offset / BUFSIZE;
		o = offset % BUFSIZE;
		n = BUFSIZE - o;
		if(n > count)
			n = count;
		p1 = dnodebuf(p, d, addr, Tfile);
		if(p1 == 0) {
			ou->err = Efull;
			goto out;
		}
		if(checktag(p1, Tfile, d->qid.path)) {
			putbuf(p1);
			ou->err = Ephase;
			goto out;
		}
		memmove(p1->iobuf+o, in->data+nwrite, n);
		p1->flags |= Bmod;
		putbuf(p1);
		count -= n;
		nwrite += n;
		offset += n;
	}
	if(CHAT(cp))
		print("	nwrite = %d\n", nwrite);

out:
	if(p)
		putbuf(p);
	if(f)
		qunlock(f);
	ou->fid = in->fid;
	ou->count = nwrite;
}
Пример #17
0
void
f_create(Chan *cp, Oldfcall *in, Oldfcall *ou)
{
	Iobuf *p, *p1;
	Dentry *d, *d1;
	File *f;
	int slot, slot1, fmod;
	int32_t addr, addr1, path;
	Qid qid;
	Tlock *t;
	Wpath *w;

	if(CHAT(cp)) {
		print("c_create %d\n", cp->chan);
		print("	fid = %d\n", in->fid);
		print("	name = %s\n", in->name);
		print("	perm = %lx+%lo\n", (in->perm>>28)&0xf,
				in->perm&0777);
		print("	mode = %d\n", in->mode);
	}

	p = 0;
	f = filep(cp, in->fid, 0);
	if(!f) {
		ou->err = Efid;
		goto out;
	}
	if(isro(f->fs->dev) || (cp != cons.chan && writegroup && !ingroup(f->uid, writegroup))) {
		ou->err = Eronly;
		goto out;
	}

	p = getbuf(f->fs->dev, f->addr, Bread);
	d = getdir(p, f->slot);
	if(!d || checktag(p, Tdir, QPNONE) || !(d->mode & DALLOC)) {
		ou->err = Ealloc;
		goto out;
	}
	if(ou->err = mkqidcmp(&f->qid, d))
		goto out;
	if(!(d->mode & DDIR)) {
		ou->err = Edir2;
		goto out;
	}
	if(cp != cons.chan && iaccess(f, d, DWRITE) && !writeallow) {
		ou->err = Eaccess;
		goto out;
	}
	accessdir(p, d, FREAD);
	if(!strncmp(in->name, ".", sizeof(in->name)) ||
	   !strncmp(in->name, "..", sizeof(in->name))) {
		ou->err = Edot;
		goto out;
	}
	if(checkname(in->name)) {
		ou->err = Ename;
		goto out;
	}
	addr1 = 0;
	slot1 = 0;	/* set */
	for(addr=0;; addr++) {
		p1 = dnodebuf(p, d, addr, 0);
		if(!p1) {
			if(addr1)
				break;
			p1 = dnodebuf(p, d, addr, Tdir);
		}
		if(p1 == 0) {
			ou->err = Efull;
			goto out;
		}
		if(checktag(p1, Tdir, d->qid.path)) {
			putbuf(p1);
			goto phase;
		}
		for(slot=0; slot<DIRPERBUF; slot++) {
			d1 = getdir(p1, slot);
			if(!(d1->mode & DALLOC)) {
				if(!addr1) {
					addr1 = p1->addr;
					slot1 = slot + addr*DIRPERBUF;
				}
				continue;
			}
			if(!strncmp(in->name, d1->name, sizeof(in->name))) {
				putbuf(p1);
				ou->err = Eexist;
				goto out;
			}
		}
		putbuf(p1);
	}
	switch(in->mode & 7) {
	case MEXEC:
	case MREAD:		/* seems only useful to make directories */
		fmod = FREAD;
		break;

	case MWRITE:
		fmod = FWRITE;
		break;

	case MBOTH:
		fmod = FREAD+FWRITE;
		break;

	default:
		ou->err = Emode;
		goto out;
	}
	if(in->perm & PDIR)
		if((in->mode & MTRUNC) || (in->perm & PAPND) || (fmod & FWRITE))
			goto badaccess;
	/*
	 * do it
	 */
	path = qidpathgen(&f->fs->dev);
	p1 = getbuf(f->fs->dev, addr1, Bread|Bimm|Bmod);
	d1 = getdir(p1, slot1);
	if(!d1 || checktag(p1, Tdir, d->qid.path)) {
		if(p1)
			putbuf(p1);
		goto phase;
	}
	if(d1->mode & DALLOC) {
		putbuf(p1);
		goto phase;
	}

	strncpy(d1->name, in->name, sizeof(in->name));
	/*
	 * bogus argument passing -- see console.c
	 */
	if(cp == cons.chan) {
		d1->uid = cons.uid;
		d1->gid = cons.gid;
	} else {
		d1->uid = f->uid;
		d1->gid = d->gid;
		in->perm &= d->mode | ~0666;
		if(in->perm & PDIR)
			in->perm &= d->mode | ~0777;
	}
	d1->qid.path = path;
	d1->qid.version = 0;
	d1->mode = DALLOC | (in->perm & 0777);
	if(in->perm & PDIR) {
		d1->mode |= DDIR;
		d1->qid.path |= QPDIR;
	}
	if(in->perm & PAPND)
		d1->mode |= DAPND;
	t = 0;
	if(in->perm & PLOCK) {
		d1->mode |= DLOCK;
		t = tlocked(p1, d1);
	}
	accessdir(p1, d1, FWRITE);
	mkqid(&qid, d1, 0);
	putbuf(p1);
	accessdir(p, d, FWRITE);

	/*
	 * do a walk to new directory entry
	 */
	w = newwp();
	if(!w) {
		ou->err = Ewalk;
		goto out;
	}
	w->addr = f->addr;
	w->slot = f->slot;
	w->up = f->wpath;
	f->wpath = w;
	f->qid = qid;
	f->tlock = t;
	f->lastra = 0;
	if(in->mode & MRCLOSE)
		fmod |= FREMOV;
	f->open = fmod;
	f->addr = addr1;
	f->slot = slot1;
	if(t)
		t->file = f;
	mkqid9p1(&ou->qid, &qid);
	goto out;

badaccess:
	ou->err = Eaccess;
	goto out;

phase:
	ou->err = Ephase;

out:
	if(p)
		putbuf(p);
	if(f)
		qunlock(f);
	ou->fid = in->fid;
}
Пример #18
0
void
f_open(Chan *cp, Oldfcall *in, Oldfcall *ou)
{
	Iobuf *p;
	Dentry *d;
	File *f;
	Tlock *t;
	Qid qid;
	int ro, fmod;

	if(CHAT(cp)) {
		print("c_open %d\n", cp->chan);
		print("	fid = %d\n", in->fid);
		print("	mode = %o\n", in->mode);
	}

	p = 0;
	f = filep(cp, in->fid, 0);
	if(!f) {
		ou->err = Efid;
		goto out;
	}

	/*
	 * if remove on close, check access here
	 */
	ro = isro(f->fs->dev) || (cp != cons.chan && writegroup && !ingroup(f->uid, writegroup));
	if(in->mode & MRCLOSE) {
		if(ro) {
			ou->err = Eronly;
			goto out;
		}
		/*
		 * check on parent directory of file to be deleted
		 */
		if(f->wpath == 0 || f->wpath->addr == f->addr) {
			ou->err = Ephase;
			goto out;
		}
		p = getbuf(f->fs->dev, f->wpath->addr, Bread);
		d = getdir(p, f->wpath->slot);
		if(!d || checktag(p, Tdir, QPNONE) || !(d->mode & DALLOC)) {
			ou->err = Ephase;
			goto out;
		}
		if(iaccess(f, d, DWRITE)) {
			ou->err = Eaccess;
			goto out;
		}
		putbuf(p);
	}
	p = getbuf(f->fs->dev, f->addr, Bread);
	d = getdir(p, f->slot);
	if(!d || checktag(p, Tdir, QPNONE) || !(d->mode & DALLOC)) {
		ou->err = Ealloc;
		goto out;
	}
	if(ou->err = mkqidcmp(&f->qid, d))
		goto out;
	mkqid(&qid, d, 1);
	switch(in->mode & 7) {

	case MREAD:
		if(iaccess(f, d, DREAD) && !writeallow)
			goto badaccess;
		fmod = FREAD;
		break;

	case MWRITE:
		if((d->mode & DDIR) ||
		   (iaccess(f, d, DWRITE) && !writeallow))
			goto badaccess;
		if(ro) {
			ou->err = Eronly;
			goto out;
		}
		fmod = FWRITE;
		break;

	case MBOTH:
		if((d->mode & DDIR) ||
		   (iaccess(f, d, DREAD) && !writeallow) ||
		   (iaccess(f, d, DWRITE) && !writeallow))
			goto badaccess;
		if(ro) {
			ou->err = Eronly;
			goto out;
		}
		fmod = FREAD+FWRITE;
		break;

	case MEXEC:
		if((d->mode & DDIR) ||
		   iaccess(f, d, DEXEC))
			goto badaccess;
		fmod = FREAD;
		break;

	default:
		ou->err = Emode;
		goto out;
	}
	if(in->mode & MTRUNC) {
		if((d->mode & DDIR) ||
		   (iaccess(f, d, DWRITE) && !writeallow))
			goto badaccess;
		if(ro) {
			ou->err = Eronly;
			goto out;
		}
	}
	t = 0;
	if(d->mode & DLOCK) {
		t = tlocked(p, d);
		if(t == 0) {
			ou->err = Elocked;
			goto out;
		}
		t->file = f;
	}
	if(in->mode & MRCLOSE)
		fmod |= FREMOV;
	f->open = fmod;
	if(in->mode & MTRUNC)
		if(!(d->mode & DAPND))
			dtrunc(p, d);
	f->tlock = t;
	f->lastra = 0;
	mkqid9p1(&ou->qid, &qid);
	goto out;

badaccess:
	ou->err = Eaccess;
	f->open = 0;

out:
	if(p)
		putbuf(p);
	if(f)
		qunlock(f);
	ou->fid = in->fid;
}
Пример #19
0
void
f_wstat(Chan *cp, Oldfcall *in, Oldfcall *ou)
{
	Iobuf *p, *p1;
	Dentry *d, *d1, xd;
	File *f;
	int slot;
	int32_t addr;

	if(CHAT(cp)) {
		print("c_wstat %d\n", cp->chan);
		print("	fid = %d\n", in->fid);
	}

	p = 0;
	p1 = 0;
	d1 = 0;
	f = filep(cp, in->fid, 0);
	if(!f) {
		ou->err = Efid;
		goto out;
	}
	if(isro(f->fs->dev) || (cp != cons.chan && writegroup && !ingroup(f->uid, writegroup))) {
		ou->err = Eronly;
		goto out;
	}

	/*
	 * first get parent
	 */
	if(f->wpath) {
		p1 = getbuf(f->fs->dev, f->wpath->addr, Bread);
		d1 = getdir(p1, f->wpath->slot);
		if(!d1 || checktag(p1, Tdir, QPNONE) || !(d1->mode & DALLOC)) {
			ou->err = Ephase;
			goto out;
		}
	}

	p = getbuf(f->fs->dev, f->addr, Bread);
	d = getdir(p, f->slot);
	if(!d || checktag(p, Tdir, QPNONE) || !(d->mode & DALLOC)) {
		ou->err = Ealloc;
		goto out;
	}
	if(ou->err = mkqidcmp(&f->qid, d))
		goto out;

	convM2D9p1(in->stat, &xd);
	if(CHAT(cp)) {
		print("	d.name = %s\n", xd.name);
		print("	d.uid  = %d\n", xd.uid);
		print("	d.gid  = %d\n", xd.gid);
		print("	d.mode = %.4x\n", xd.mode);
	}

	/*
	 * if chown,
	 * must be god
	 */
	while(xd.uid != d->uid) {
		if(wstatallow)			/* set to allow chown during boot */
			break;
		ou->err = Enotu;
		goto out;
	}

	/*
	 * if chgroup,
	 * must be either
	 *	a) owner and in new group
	 *	b) leader of both groups
	 */
	while(xd.gid != d->gid) {
		if(wstatallow || writeallow)		/* set to allow chgrp during boot */
			break;
		if(d->uid == f->uid && ingroup(f->uid, xd.gid))
			break;
		if(leadgroup(f->uid, xd.gid))
			if(leadgroup(f->uid, d->gid))
				break;
		ou->err = Enotg;
		goto out;
	}

	/*
	 * if rename,
	 * must have write permission in parent
	 */
	if(xd.name[0] == 0)
		strncpy(xd.name, d->name, sizeof(xd.name));
	while(strncmp(d->name, xd.name, sizeof(d->name)) != 0) {
		if(checkname(xd.name)) {
			ou->err = Ename;
			goto out;
		}

		if(strcmp(xd.name, ".") == 0 || strcmp(xd.name, "..") == 0) {
			ou->err = Ename;
			goto out;
		}

		/*
		 * drop entry to prevent lock, then
		 * check that destination name is unique,
		 */
		putbuf(p);
		for(addr=0;; addr++) {
			p = dnodebuf(p1, d1, addr, 0);
			if(!p)
				break;
			if(checktag(p, Tdir, d1->qid.path)) {
				putbuf(p);
				continue;
			}
			for(slot=0; slot<DIRPERBUF; slot++) {
				d = getdir(p, slot);
				if(!(d->mode & DALLOC))
					continue;
				if(!strncmp(xd.name, d->name, sizeof(xd.name))) {
					ou->err = Eexist;
					goto out;
				}
			}
			putbuf(p);
		}

		/*
		 * reacquire entry
		 */
		p = getbuf(f->fs->dev, f->addr, Bread);
		d = getdir(p, f->slot);
		if(!d || checktag(p, Tdir, QPNONE) || !(d->mode & DALLOC)) {
			ou->err = Ephase;
			goto out;
		}

		if(wstatallow || writeallow) /* set to allow rename during boot */
			break;
		if(!d1 || iaccess(f, d1, DWRITE)) {
			ou->err = Eaccess;
			goto out;
		}
		break;
	}

	/*
	 * if mode/time, either
	 *	a) owner
	 *	b) leader of either group
	 */
	while(d->mtime != xd.mtime ||
	     ((d->mode^xd.mode) & (DAPND|DLOCK|0777))) {
		if(wstatallow)			/* set to allow chmod during boot */
			break;
		if(d->uid == f->uid)
			break;
		if(leadgroup(f->uid, xd.gid))
			break;
		if(leadgroup(f->uid, d->gid))
			break;
		ou->err = Enotu;
		goto out;
	}
	d->mtime = xd.mtime;
	d->uid = xd.uid;
	d->gid = xd.gid;
	d->mode = (xd.mode & (DAPND|DLOCK|0777)) | (d->mode & (DALLOC|DDIR));

	strncpy(d->name, xd.name, sizeof(d->name));
	if(wstatallow) {
		p->flags |= Bmod;
		if(xd.atime)
			d->atime = xd.atime;
		if(xd.mtime)
			d->mtime = xd.mtime;
	} else
		accessdir(p, d, FWSTAT);

out:
	if(p)
		putbuf(p);
	if(p1)
		putbuf(p1);
	if(f)
		qunlock(f);
	ou->fid = in->fid;
}