[alt.sources] chmod args

ignatz@chinet.chi.il.us (Dave Ihnat) (06/02/89)

>In article <12743@ihlpy.ATT.COM> bdavies@ihlpy.UUCP (55314-Davies,B.) writes:
>Really.  *I* know what you all mean, but why does everyone teach the
>octal way when these mnemonic ways exist that are so nice and easy to
>understand for everyone?  Don't you all believe in abstraction?

Actually, they still have two different and useful functions.  The mnemonic
method is a mask, while using the octal is a total reset.  So, the mnemonic
is simpler if I just want to toggle a particular permission; I don't need
to be sure to not destroy other bits:

Old permission	Desired Permission	Octal arg.	Mnemonic arg.
777		774			774		o-wx,o+r

Notice that if I didn't know the old permission--say, in a shell script--
the mnemonic, while still a bit verbose, is still simpler than the shellish
to extract the old values, mask in only those I want to change, and then
execute the chmod.

On the other hand, if I'm installing a program and have definite ideas
about the permissions I want to set, then the octal form is cleaner:

Desired Permission	Octal arg.	Mnemonic arg.
2710			2710		u+rwx,g+xs,g-rw,o-rwx

At this point, the octal mask is cleaner, since you still have to do the mental
dance to interpret the now rather long mnemonic string.

Finally, I firmly believe that it's an absolute necessity for even casual
Unix users to fully understand file permissions; most security violations
on Unix can be traced to user carelessness, either due to misunderstanding or
simple lack of care when dealing with file permissions.  There are some quite
decent interactive tools in the PD to allow naieve users to manipulate their
permissions without resort to either bitmasks or the rather dense mnemonics
of chmod, if this is a problem.

rsalz@bbn.com (Rich Salz) (06/02/89)

[ Note the follow-ups.]

Why hasn't anyone written a chmod(1) that takes a bloody "rwsr-xr-x" string?
	/r$
-- 
Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.

faigin@sunstroke.aero.org (Daniel P. Faigin) (06/02/89)

In article <8605@chinet.chi.il.us> ignatz@chinet.chi.il.us (Dave Ihnat) writes:
>>In article <12743@ihlpy.ATT.COM> bdavies@ihlpy.UUCP (55314-Davies,B.) writes:
>>Really.  *I* know what you all mean, but why does everyone teach the
>>octal way when these mnemonic ways exist that are so nice and easy to
>>understand for everyone?  Don't you all believe in abstraction?
>
>Actually, they still have two different and useful functions.  The mnemonic
>method is a mask, while using the octal is a total reset.  So, the mnemonic
>is simpler if I just want to toggle a particular permission; I don't need
>to be sure to not destroy other bits....
>On the other hand, if I'm installing a program and have definite ideas
>about the permissions I want to set, then the octal form is cleaner.

RTFM


  Symbolic Modes
     A symbolic mode has the form:

          [ who ] op permission [ op permission ]...

     who is a combination of:
     u    user's permissions
     g    group permissions
     o    others
     a    all, or ugo

     op is one of:
     +    to add the permission
     -    to remove the permission
     =    to assign the permission explicitly (all other bits for that
          category, owner, group, or others, will be reset). 

Hence, his example where he needs 
	chmod 2710
can be written much cleaner as:
	chmod u=rwx,g=xs,o-rwx

Daniel


Work :The Aerospace Corp M8/055 * POB 92957 * LA, CA 90009-2957 * 213/336-3149
Home :8333 Columbus Avenue #17  * Sepulveda CA 91343            * 818/892-8555
Email:faigin@aerospace.aero.org (or) Faigin@dockmaster.ncsc.mil               
Voicemail: 213/336-5454 Box#3149 * "Take what you like, and leave the rest"   

woods@cbnewsc.ATT.COM (Warren D. Swan) (06/02/89)

In article <8605@chinet.chi.il.us> ignatz@chinet.chi.il.us (Dave Ihnat) writes:
>>In article <12743@ihlpy.ATT.COM> bdavies@ihlpy.UUCP (55314-Davies,B.) writes:
>>Really.  *I* know what you all mean, but why does everyone teach the
>>octal way when these mnemonic ways exist that are so nice and easy to
>>understand for everyone?  Don't you all believe in abstraction?
>
>Actually, they still have two different and useful functions.  The mnemonic
>method is a mask, while using the octal is a total reset.

Whoops!  The rest of your article is tainted by this mistaken idea.  You've
either forgotten, or never learned about the = symbol in the mnemonic method.
For example:

>Old permission	Desired Permission	Octal arg.	Mnemonic arg.
>777		774			774		o-wx,o+r

Should be:                                              o=r
(3 characters either way!)

And more obviously:

>Desired Permission	Octal arg.	Mnemonic arg.
>2710			2710		u+rwx,g+xs,g-rw,o-rwx

Should be:                              u=rwx,g=xs,o=
                                         ^
                                         Could be +, but to be consistent...

The mnemonic is still longer, but doesn't take the mental gymnastics that your
expression requires.  Plus it still allows the abstraction referred to in
who-knows-whose article (the references are getting thick!).


>Finally, I firmly believe that it's an absolute necessity for even casual
>Unix users to fully understand file permissions; most security violations
>on Unix can be traced to user carelessness, either due to misunderstanding or
>simple lack of care when dealing with file permissions.

Agreed!
--
Warren D. Swan  (WooDS)     Y n n ____ __      You can't tell which way a train
AT&T Bell Laboratories     -(((((([__]/__]     went by looking at the tracks.
Naperville, Illinois       /o-OOOOO~~  oo
att!cblph!woods         #####################  FRISCO 1630 Decapod (2-10-0) IRM

rogerk@mips.COM (Roger B.A. Klorese) (06/03/89)

In article <8605@chinet.chi.il.us> ignatz@chinet.chi.il.us (Dave Ihnat) writes:
>Actually, they still have two different and useful functions.  The mnemonic
>method is a mask, while using the octal is a total reset. 

Mnemonics may be used for total reset as well.

>On the other hand, if I'm installing a program and have definite ideas
>about the permissions I want to set, then the octal form is cleaner:
>
>Desired Permission	Octal arg.	Mnemonic arg.
>2710			2710		u+rwx,g+xs,g-rw,o-rwx

Proper mnemonic arg.: u=rwx,g=xs,o=


>At this point, the octal mask is cleaner, since you still have to do the mental
>dance to interpret the now rather long mnemonic string.

No, you don't.

-- 
ROGER B.A. KLORESE      MIPS Computer Systems, Inc.      phone: +1 408 720-2939
928 E. Arques Ave.  Sunnyvale, CA  94086             voicemail: +1 408 991-7802
{ames,decwrl,pyramid}!mips!rogerk                     rogerk@servitude.mips.COM
"I want to live where it's always Saturday."  -- Guadalcanal Diary

dww@cbnewsl.ATT.COM (david.w.weatherford) (06/03/89)

In article <8605@chinet.chi.il.us> ignatz@chinet.chi.il.us (Dave Ihnat) writes:
>>In article <12743@ihlpy.ATT.COM> bdavies@ihlpy.UUCP (55314-Davies,B.) writes:
>>Really.  *I* know what you all mean, but why does everyone teach the
>>octal way when these mnemonic ways exist that are so nice and easy to
>>understand for everyone?  Don't you all believe in abstraction?
>
>Actually, they still have two different and useful functions.  The mnemonic
>method is a mask, while using the octal is a total reset.  So, the mnemonic
>is simpler if I just want to toggle a particular permission; I don't need
>to be sure to not destroy other bits:
>
>Old permission	Desired Permission	Octal arg.	Mnemonic arg.
>777		774			774		o-wx,o+r
>
>Notice that if I didn't know the old permission--say, in a shell script--
>the mnemonic, while still a bit verbose, is still simpler than the shellish
>to extract the old values, mask in only those I want to change, and then
>execute the chmod.
>
>On the other hand, if I'm installing a program and have definite ideas
>about the permissions I want to set, then the octal form is cleaner:
>
>Desired Permission	Octal arg.	Mnemonic arg.
>2710			2710		u+rwx,g+xs,g-rw,o-rwx
>
>At this point, the octal mask is cleaner, since you still have to do the mental
>dance to interpret the now rather long mnemonic string.
>
>Finally, I firmly believe that it's an absolute necessity for even casual
>Unix users to fully understand file permissions; most security violations
>on Unix can be traced to user carelessness, either due to misunderstanding or
>simple lack of care when dealing with file permissions.  There are some quite
>decent interactive tools in the PD to allow naieve users to manipulate their
>permissions without resort to either bitmasks or the rather dense mnemonics
>of chmod, if this is a problem.

Newsgroups: alt.sources
Subject: Re: chmod args (was Re: Need a "watching" program)
Summary: You can used "chmod =rw foo" as easily as "chmod 666"
Expires: 
References: <8923@csli.Stanford.EDU> <11680@s.ms.uky.edu> <8928@csli.Stanford.EDU> <12743@ihlpy.ATT.COM> <1953@ur-cc.UUCP> <2126@amelia.nas.nasa.gov> <8605@chinet.chi.il.us>
Sender: 
Reply-To: dww@cbnewsl.ATT.COM (david.w.weatherford)
Followup-To: 
Distribution: usa
Organization: AT&T Bell Laboratories
Keywords: chmod

In article <8605@chinet.chi.il.us> ignatz@chinet.chi.il.us (Dave Ihnat) writes:
:>In article <12743@ihlpy.ATT.COM> bdavies@ihlpy.UUCP (55314-Davies,B.) writes:
:>Really.  *I* know what you all mean, but why does everyone teach the
:>octal way when these mnemonic ways exist that are so nice and easy to
:>understand for everyone?  Don't you all believe in abstraction?
:
:Actually, they still have two different and useful functions.  The mnemonic
:method is a mask, while using the octal is a total reset.

This is not so.  Mnemonic mode has the "=" operator to do "total reset".

:							    So, the mnemonic
:is simpler if I just want to toggle a particular permission; I don't need
:to be sure to not destroy other bits:

:Old permission	Desired Permission	Octal arg.	Mnemonic arg.
:777		774			774		o-wx,o+r

The above example could be expressed "o=r".  Same number of characters,
no danger of munging other bits.

:Notice that if I didn't know the old permission--say, in a shell script--
:the mnemonic, while still a bit verbose, is still simpler than the shellish
:to extract the old values, mask in only those I want to change, and then
:execute the chmod.

:On the other hand, if I'm installing a program and have definite ideas
:about the permissions I want to set, then the octal form is cleaner:

:Desired Permission	Octal arg.	Mnemonic arg.
:2710			2710		u+rwx,g+xs,g-rw,o-rwx

:At this point, the octal mask is cleaner, since you still have to do the mental
:dance to interpret the now rather long mnemonic string.

Use the "=" operator; in most cases it is (almost) as succinct.  Such as,
=rw for 666, =rwx for 777, =r for 444.  If you want different permissions
for each of u, g, and o, then the string can be a bit verbose, as in
"u=rwx,g=rx,o=r" for 751.  Even so, the mnemonic form is more, uh, well,
mnemonic!  The 2710 above could be expressed as "u=rwx,g=xs,o=" much more
succinctly.  Still not as short as the octal form, but clearer, and no
mental gymnastics required.

:Finally, I firmly believe that it's an absolute necessity for even casual
:Unix users to fully understand file permissions; most security violations
:on Unix can be traced to user carelessness, either due to misunderstanding or
:simple lack of care when dealing with file permissions.

No argument here.

:							  There are some quite
:decent interactive tools in the PD to allow naieve users to manipulate their
:permissions without resort to either bitmasks or the rather dense mnemonics
:of chmod, if this is a problem.

I still think that the mnemonics are not "dense" -- I rather like them, but
each to his own.

Dave Weatherford			AT&T Bell Laboratories
attunix!dww				Summit, NJ

guy@auspex.auspex.com (Guy Harris) (06/03/89)

>On the other hand, if I'm installing a program and have definite ideas
>about the permissions I want to set, then the octal form is cleaner:
>
>Desired Permission	Octal arg.	Mnemonic arg.
>2710			2710		u+rwx,g+xs,g-rw,o-rwx

Oh, good grief.  Try "u=rwx,g=xs,o=" instead.  Yes, Virginia, there
really *is* an "=" operator in the syntax for the mode argument to
"chmod" - and yes, on those *very* rare occasions when I do a "chmod" to
set the modes to some particular value rather than changing the modes, I
use it.  You see, I think of the desired permission as "rwx--s---", not
2710....

tale@pawl.rpi.edu (David C Lawrence) (06/03/89)

/*                               -*- Mode: C -*- 
 * permit.c --- change the permission of a file/directory using long form
 * Author          : David C Lawrence          <tale@pawl.rpi.edu>
 * Created On      : Sat Jun  3 03:32:10 1989
 * Last Modified By: David C Lawrence
 * Last Modified On: Sat Jun  3 04:04:08 1989
 * Update Count    : 4
 * Status          : Works just fine for BSD/Sun, maybe SYSV
 */

/*
 * Usage is: permit rwxrwxrwx-pattern file(s)
 *
 * This deals fine with all current permission schemes on Sun/BSD
 * (and mostly on SYSV) systems of which I am aware. I'm not sure
 * how portable it is beyond that.
 *
 * It will accept patterns like rwsr-S--t (bozotic, I realize) without
 * complaint and try to permit accordingly. It even gives you a warning
 * message if you try to set the sticky bit on a file without being
 * the superuser (the regular chmod doesn't).
 *
 * Caveat: I couldn't get to a SYSV machine to try this out; I
 * have a feeling sticky bit stuff might be wrong there, but I am
 * not sure.
 *
 * BUGS: none that I know of at the moment, but it does have really
 *       dorky error messages.
 */

#include <malloc.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>

char *pname;                    /* for the programme name (error messages) */
extern int errno;
extern char *sys_errlist[];
extern char *strcpy();

int
decipher_permission(perm_str)
     char *perm_str;

{
  int loop, ch, perm=0;
  
  for (loop=0;loop<9;loop++) {
    ch=perm_str[loop];
    switch (ch) {               /* A switch statement probably isn't the   */
    case 'r':                   /* most efficient, but it only gets called */
      if (loop%3 != 0) {        /* nine times anyway. */
        (void)fprintf(stderr,"%s: 'r'ead permission misplaced\n",pname);
        exit(99);
      }
      perm |= S_IREAD >> ((int)(loop/3))*3;
      break;
    case 'w':
      if (loop%3 != 1) {
        (void)fprintf(stderr,"%s: 'w'rite permission misplaced\n",pname);
        exit(99);
      }
      perm |= S_IWRITE >> ((int)(loop/3))*3;
      break;
    case 'x':
      if (loop%3 != 2) {
        (void)fprintf(stderr,"%s: e'x'ecute permisson misplaced\n",pname);
        exit(99);
      }
      perm |= S_IEXEC >> ((int)(loop/3))*3;
      break;
    case 'S':
    case 's':
    case 'l':                   /* 'l' is SYSV 'S' for setgid (?) */
      if (loop%3 != 2 || loop == 8 || (ch == 'l' && loop != 5)) {
        (void)fprintf(stderr,"%s: 's'et[ug]id permission misplaced\n",pname);
        exit(99);
      }
      perm |= (loop==2 ? S_ISUID : S_ISGID);
      /* add execute permission, too */
      if (ch == 's') perm |= S_IEXEC >> ((int)(loop/3))*3;
      break;
    case 'T':
    case 't':
      if (loop != 8) {
        (void)fprintf(stderr,"%s: s't'icky permission misplaced\n",pname);
        exit(99);
      }
      perm |= S_ISVTX;
      /* add execute permission, too */
      if (ch == 't') perm |= S_IXOTH;
      break;
    case '-':
      break;
    default:
      (void)fprintf(stderr,"%s: unknown permission: %c\n",pname,ch);
      exit(99);
    }
  }
  return(perm);
}

int
main(argc,argv)
     int argc;
     char **argv;

{
  int permission, rc=0;
  struct stat *statbuf;

  if (argc < 3 || strlen(argv[1]) != 9) {
    (void)fprintf(stderr,"Usage: %s 9-char-permission file(s)\n",argv[0]);
    exit(101);
  }
  if((pname=malloc((unsigned)strlen(argv[0])+1))==NULL) {
    (void)fprintf(stderr,"%s: malloc: couldn't allocate space\n",argv[0]);
    exit(102);
  }
  (void)strcpy(pname,argv[0]);
  permission=decipher_permission(argv[1]);
  for(argc--;argc>1;argc--) {
    if (chmod(argv[argc],permission) == -1) {
      (void)fprintf(stderr,"%s: %s: %s\n",pname,argv[argc],sys_errlist[errno]);
      rc++;
    } else {
      (void)stat(argv[argc], statbuf); /* since chmod succeeded, stat should */
      /* could possibly check here for clearing of setgid, too */
      if ((geteuid() != 0) && (permission & S_ISVTX) &&
          !(statbuf->st_mode & S_IFDIR)) {
        (void)fprintf(stderr,
                      "%s: couldn't set sticky bit for %s\n",pname,argv[argc]);
        rc++;
      }
    }
  }
  /* exit with the number of files we were not able to permit as requested */
  exit(rc);
}
--
 (setq mail '("tale@pawl.rpi.edu" "tale@itsgw.rpi.edu" "tale@rpitsmts.bitnet"))

bzs@bu-cs.BU.EDU (Barry Shein) (06/04/89)

Many years ago I wrote a simple shell script for new users "setfile"
which took either "private" or "public" and a list of one or more file
or dir names. It then set the files to reasonable values (private=user
only, public=everyone could read and/or execute, only user write in
all cases.) So:

	setpriv public a b c
	setpriv private x y z

Seemed to eliminate a lot of errors. The only tricky part of the
script is propagating the execute bit rationally. Also that some shell
tests do "the wrong thing" for root, but root shouldn't use the script
(but of course it happened, yielding odd results.)

Of course, if they want more control they learn chmod.

I've attached the source, ugh, it's in csh, well, it was a long time
ago...It was meant to be very simple, rather than posting bugs or
fixes (particularly to me) I'd suggest just looking at it as an
example (or enough sources to justify this note :-)

#!/bin/csh
#
#	Simplified chmod script
#
#	setfile [public|private] files....
#
if($#argv == 0) goto usage
#
#	The obscure problem here is that if(-x file)
#	always returns true for root.
#
if(`whoami` == root) then
	echo "Doesn't work correctly for root, sorry -- use chmod"
	exit(0)
endif

if($argv[1] == 'private') goto private
if($argv[1] == 'public')  goto public
if($argv[1] == 'execute') goto execute
goto usage
private:
shift
foreach f ($*)
	set perm=600
	if(-x $f) set perm=700
	chmod $perm $f
end
exit(0)
public:
shift
foreach f ($*)
	set perm=644
	if(-x $f) set perm=755
	chmod $perm $f
end
exit(0)
execute:
shift
foreach f ($*)
	chmod u+x $f
end
exit(0)
usage:
	echo "Usage: " $0 "[private|public|execute]" "file[s]"
	exit(1)
-- 
	-Barry Shein

Software Tool & Die, Purveyors to the Trade
1330 Beacon Street, Brookline, MA 02146, (617) 739-0202

mackenzi@thor.acc.stolaf.edu (David MacKenzie) (06/05/89)

In article <32248@bu-cs.BU.EDU> bzs@bu-cs.BU.EDU (Barry Shein) writes:
>
>Many years ago I wrote a simple shell script for new users "setfile"
>which took either "private" or "public" and a list of one or more file
>or dir names. It then set the files to reasonable values (private=user
>only, public=everyone could read and/or execute, only user write in
>all cases.) So:
>
>	setpriv public a b c
>	setpriv private x y z
>
>Seemed to eliminate a lot of errors. The only tricky part of the
>script is propagating the execute bit rationally. Also that some shell
>tests do "the wrong thing" for root, but root shouldn't use the script
>(but of course it happened, yielding odd results.)

Here's another approach that I use: two scripts, 'private' and 'public':

#!/bin/sh
# private - remove group and other permissions
# Usage: private file . . .
exec chmod go-rwx $*


#!/bin/sh
# public - copy user permissions into group and other (umask considered)
# Usage: public file . . .
exec chmod =u $*
-- 
David MacKenzie
mackenzi@thor.stolaf.edu or edf@rocky2.rockefeller.edu