Operating System - OpenVMS
1827703 Members
2966 Online
109967 Solutions
New Discussion

Re: Enable/Disable dynamic identifiers in C.

 
SOLVED
Go to solution
Oscar van Eijk
Occasional Advisor

Enable/Disable dynamic identifiers in C.

Hi All,

I need to write some C code that can handle identifiers with the Dynamic attribute.

It needs to lookup if an ident has been granted (but I suppose $FIND_HOLDER will do) and if so en/disable like $ SET RIGHTS_LIST would do.

Using $PERSONA is no option, since (a) the software should run on VAX and Alpha anb (b) IMPERSONATE privs is not (always) available.

Any suggestions?

Tnx,
Oscar
19 REPLIES 19
Wim Van den Wyngaert
Honored Contributor

Re: Enable/Disable dynamic identifiers in C.

Put the code in a shareable image and install it with privs. Then link your program with it.

Wim
Wim
Wim Van den Wyngaert
Honored Contributor

Re: Enable/Disable dynamic identifiers in C.

Or install the whole program with privs.

Wim
Wim
Hoff
Honored Contributor

Re: Enable/Disable dynamic identifiers in C.

Rather than installing with privileges, I tend to prefer using "Subsystem Identifiers". These will work like installing with privileges, though avoid the broad security implications of having those privileges. Subsystem identifiers are more targeted, and more controllable. (Though unlike INSTALL and privileges, subsystem identifiers are granted via the ACL. Not via INSTALL.)

Put another way, privileges can potentially be more powerful than strictly necessary for various application requirement(s). The identifiers can provide a more targeted solution.

FWIW, the IMPERSONATE (and formerly known as DETACH) privilege is seriously powerful, too. It's an ALL-class privilege, and easily able to grant any privilege and any access that might be required. It's a BYPASS-grade privilege.

For process creation under another UIC (if that's where you're going), you can also use $sndjbc or such. With privileges.)

I tend to use a server for this sort of function, and to define the interface between the client processes and the privileged process(es).

And as for the system service programming interface for the identifier question, do look to the $GRANTID and $REVOKID services.
Oscar van Eijk
Occasional Advisor

Re: Enable/Disable dynamic identifiers in C.

Thanks for your answers, but I think I need te be a bit more clear about what I need.

The software is a development environment where users have several roles (like developer, integrator, admin...) for several products.

The filesystem (incl. CMS) is protected using ACL's, so depending on which role is being selected, the proper identifiers have to be enabled. We're using UAF's dynamic attributes when the idents are granted.

Can $GRANTID/$REVOKID do this? I understood that's only for the the rightslist database...
Jan van den Ende
Honored Contributor
Solution

Re: Enable/Disable dynamic identifiers in C.

Oscar,

om te beginnen: WELKOM bij het VMS forum!

The issue.

You _DID_ state that the identifiers ARE all created with /ATTRIB=DYNAMIC, right?

Now, if you(r system manager) also UAF> GRANTs them with tis attibute, THEN __NO__ extra privs are needed to SET RIGHTS EN/DISable them.

Minor gripe (of mine): upon login, such identifiers are always ENabled. Several times in the past years I have been advocating the possibility to have them initially disabled, but in vain sofar.

Mind, this _IS_ on the assumption that your users in several roles ARE to be trusted to behave according to their role-of-the-moment.

If you seek to enforce it, then you really should look serouously into the possibilities offered by Protected Subsystems.

But if your users also have to be able to assume "admin" roles (and I assume that also applies to the VMS environment), then you ARE down to good old trust...

(we HAVE implemented to delegate certain system management functionalities from captive menus, but that is a complete config in its own right).

Tell us more, and we probably can help you better.

Proost.

Have one on me.

jpe
Don't rust yours pelled jacker to fine doll missed aches.
Oscar van Eijk
Occasional Advisor

Re: Enable/Disable dynamic identifiers in C.

Hoi Jan,

Dank je :)

Identifiers are created with /atrrib=dyn indeed. I know they're default enabled, we handle that in the SYLOGIN.
It's not that the users can't be trusted, but the environment is pretty complex and it's just to prevent mistakes (the admin role also does the actual grant).

The issue is, the software that should enable an identifier, has to be written in C for other reasons, so what I'm looking for is a system service (or a SET RIGHTS /JOB :-S).

Op je gezondheid,
Oscar

John Gillings
Honored Contributor

Re: Enable/Disable dynamic identifiers in C.

Oscar,

I'd have expected this to be a $GRANTID, but I can't see a combination of arguments that does it. If you have access to a results disk (OpenVMS listings), check out the code for SETRIGHTS to see how they do it.



re: Wim

>Put the code in a shareable image and
>install it with privs. Then link your
>program with it.

Sigh... Wim, you need to write out 100 times:

"There is NO SUCH THING as a privileged shareable image"

Although it's possible to install a shareable image with the /PRIVILEGE option - at least in the sense that you won't get an error message, it doesn't do anything (unless the image is activated as an executable image).

If you want to create a shareable image which executes with elevated privileges, it needs to be a user written system service. This is a whole different ballgame from linking a bunch of routines into a shareable image.
A crucible of informative mistakes
Jon Pinkley
Honored Contributor

Re: Enable/Disable dynamic identifiers in C.

Yes, $GRANTID is what adds an identifier to the process rightslist. It is confusing, since the AUTHORIZE (UAF) program uses the grant command when what it is really using is $ADD_HOLDER, which modifies the RIGHTSLIST file.

Subsystem identifiers are good when a program does all access to the protected objects. However, that does not seem to satisfy Oscar's requirement of "changing role".

As has been mentioned by others, the dynamic attribute specifically allows a non-privileged user to add and remove the identifier from the process rights. Therefore anything using it for security related issues is (nearly) pointless. It is a bit like granting a user an authorized privilege that is not in their default privilege set; all that is needed to enable the privilege is set proc/priv=all and all authorized privileges (other than SETPRV) will be turned on in the current privilege mask.

If that is "good enough", then Oscar could implement the solution with a command procedure. However, Oscar specifically stated this had to be done with a C program, without stating the reason for the restriction.

If your are going to do this with a program, this is what I would do, although I would verify that it works with CMS before writing a program.

Instead of using the dynamic attribute, I would use the noaccess attribute, and then use the program to turn the noaccess attribute off to enable the role, and turn the noaccess attribute back on to disable the role.

Create an identifier for each "role" with the attributes (resource,noaccess). Grant this identifier to every user that is authorized for the role, with the same attributes (resource,noaccess). Protect the object with an ACL specifying the identifier so that the special access is only available via the role identifiers.

The noaccess attribute will disable the ability of the users to access the objects unless the noaccess attribute is removed with $GRANTID. This will require privilege, but I think you are going to need the image installed with privilege anyway, to be able to use the $GRANTID system service, which states it requires a minimum of CMKRNL.

So your enable_role program will need to do the following (with at least CMKRNL priv):

1. Get requested role from user (via command line option).

2. Copy users input to local storage, and then validate what is in the local buffer. If not valid input then quit.

3. Determine identifier associated with role, and convert this ASCII ID to binary with $ASCTOID.

4. Determine if process has the identifier enabled with $GETJPI item JPI$_RIGHTSLIST (with your buffer based on size returned by item JPI$_RIGHTS_SIZE). This returns an array of identifiers and their associated attributes. Scan the list for the binary value returned by $ASCTOID. If the identifier is not found, then the user is not authorized for the role; exit. If found, look at the attribute longword for the KGB$M_NOACCESS bit. If the noaccess attribute is present, then you must remove it by calling $GRANTID.

5. Audit the change if needed. Be especially careful when doing any file opens to restrict to use of trusted logical names.

I didn't write a program to do all this, but I am reasonably sure it will work, based on the following test: created an identifier, granted the identifier to a non-privileged user, logged into that non-prived username, attempted to access files that only allowed access based on the identifier (this failed). Then from a process with CMKRNL enabled, used

$ set rights/enable/attribute=(nonoaccess)/id= ident

And then verified that the non-prived process could access the directory. The program should have the same effect for the process running the program as the set rights/enable shown above does for another process.

Good luck,

Jon
it depends
Jan van den Ende
Honored Contributor

Re: Enable/Disable dynamic identifiers in C.

Oscar,
as other indicated, $GRANTID is up to the trick, and if I read your OP correctly, may just be all you need.

Re Jon:

>>>
Subsystem identifiers are good when a program does all access to the protected objects. However, that does not seem to satisfy Oscar's requirement of "changing role".
<<<

Here I have to disagree.
With the slight extra requirement that no two different roles can use the same image.
All that needs to be done is enable protected subsystems on the disk(s) holding the executablesm defining role-specific subsystem idenfifiers, and installing the images with the relevant role-specific identifiers. Now all that remains is to (dis)allow access to role-specific files (other than the images) with ACEs that specify the subsystem idents.
Should you need the same imagefor different roles, then you will need two different copies, and just treat them as unrelated.

hth

Proost.

Have one on me.

jpe
Don't rust yours pelled jacker to fine doll missed aches.
Oscar van Eijk
Occasional Advisor

Re: Enable/Disable dynamic identifiers in C.

Hi guys,

Thanks all ye for your help.
The answer I was hoping for was: "Use this system service: [...]", but at least now I know why I couldn't find one.

I didn't bother to check further on SET RIGHTS, but it turns out that image is installed w/ privs also.

I'm not quite sure which solution I'll go for yet, but you provided me with enough info to pick one.
Wim Van den Wyngaert
Honored Contributor

Re: Enable/Disable dynamic identifiers in C.

John,

I never used shareable images with privs so sorry for my bad advise.

Can I use repeat in tpu to write my punishment ?

Wim
Wim
John Gillings
Honored Contributor

Re: Enable/Disable dynamic identifiers in C.

Oscar,

>I didn't bother to check further on
>SET RIGHTS, but it turns out that
>image is installed w/ privs also.

That doesn't necessarily mean that privilege is required for this particular operation. It's definitely worth checking out the source to see how the /ENABLE/DISABLE is done, and determine if privilege is required. (When you find out, please post it here so it's documented somewhere! ;-)

Note that with appropriate privilege (CMKRNL) you can do SET RIGHT/[EN|DIS]ABLE/ID= to affect the rights list of another process. You could therefore use SPAWN or system() to do the enable or disable.

Since you don't want the caller to be privileged, this will get a bit ugly... you could write a program installed with CMKRNL privilege that accepts three parameters - a PID, the target identifier name and an enable/disable flag. That program would confirm that the target PID is in the ancestral chain of the current process - something like:

pid=selfpid
master=$GETJPI(pid,"MASTER_PID")
ok=false
do while NOT ok AND pid <> master
ok= targetpid==pid
pid=$GETJPI(pid,"OWNER")
end while

If the target PID checks out, SPAWN a privileged subprocess to execute the SET RIGHTS command.

As long as this isn't something you're doing thousands of times an hour, spawning two processes to flip one rights identifier isn't pretty, but it's not too much of an issue. The same code should run on VAX, Alpha and IA64. (Oh, and note that on older versions of OpenVMS "IMPERSONATE" privilege is called "DETACH")
A crucible of informative mistakes
John Gillings
Honored Contributor

Re: Enable/Disable dynamic identifiers in C.

re Wim,

> Can I use repeat in tpu to write
>my punishment ?

:-) As long as it makes you remember!

Unfortunately "privileged shareable image" is a widespread OpenVMS myth. They do not, and cannot exist (some cursory analysis will show that if they existed, OpenVMS security would not!)

To try and stem the spread of the myth, it's necessary to counter any claim of existence with a proximal statement "There is NO SUCH THING as a privileged shareable image!"

You can achieve the effect with a User Written System Service (UWSS), but they're very tricky to write and tend to generate bugchecks during development. See the Linker Manual for details.
A crucible of informative mistakes
Jon Pinkley
Honored Contributor

Re: Enable/Disable dynamic identifiers in C.

Oscar,

Can you tell us if everything done while in the "role" is done by the C program, or was the plan to run the program which will enable extra access and then return to DCL leaving the enhanced capability in place until it is specifically disabled by running a program to change role back to "normal".

You specifically mentioned CMS. I believe there is an API for CMS. If that is the case, then at least in theory it would be possible to write a program to do the authentication of role, and then the CMS tasks, all under control of the program. If that is the case, then protected subsystems will work. On the other hand, if you want to return to the DCL prompt and still have the enhanced capabilities, I am not aware of any way to do that using protected subsystem identifiers.

So, if you plan to do everything inside the program, then we can provide more details about protected subsystem identifiers, and how they are setup and used.

Jon
it depends
Oscar van Eijk
Occasional Advisor

Re: Enable/Disable dynamic identifiers in C.

@John; If SETRIGHTS uses $GRANTID, CMKRNL is required; it's installed with that, so I don't expect any surprises there :-S
I'll see what more I can found out and keep you updated.

@Jon; The software will return control to DCL. It must setup an environment for the developer (or whatever the selected role) to work on, including target system (CPU, VMS version, layered products to build with), proper CMS library (or CVS server and root for some projects), and a lot more.
The software does have an own CLI (of course supporting all exected cmd, including SPAWN), so I don't simply wanna install it with privs :-/
Jon Pinkley
Honored Contributor

Re: Enable/Disable dynamic identifiers in C.

Oscar,

Given your requirements to return control to DCL, I know of no way to use protected subsystem identifiers, which have the effect of "granting an identifier to an image", much like privileges are granted to an image when it is installed with privs.

So, you could use $GRANTID/$REVOKID from an image installed with CMKRNL privilege to do what you originally asked (granting/revoking a dynamic id), or $GRANTID to turn off and on the noaccess attribute.

However, here's another possibility that may allow you to get the control you want, without all the hassle of writing a safe version of a program to be installed with CMKRNL privilege (which is an ALL class priv).

On Hunter Goatley's VMS freeware archives is a program, JUMP, which allows specified users to login to another username and have a logfile created. This is controlled by a text file that specifies what users can jump and to what username(s) they can jump to. It does this by creating a pseudo terminal (FT device), and then creating a process, and as such the user does not need to know the password of the account being jumped to; in fact the target username can have interactive access disabled in UAF and the account can still be used via JUMP. This is actually a useful attribute, as even if someone guesses the password, they will not be able to log into the account in the normal manner.

The idea would be to create a username for each role/real person and set this username up with the privileges/identifiers needed for the role. Then the user from their normal non-privileged account would jump to the role account to do the work, and logout when they were done with the role specific duties. A log file can be created that is inaccessible from the "jumped from" or "jumped to" users, given neither of those username has privileges that would allow them to see the files for another user, i.e. if they don't have SYSPRV (and are not a member of a UIC group <= MAXSYSGRP), READALL or BYPASS priv.

While this doesn't specifically answer your question about enabling/disabling dynamic identifiers, I think it would be a possible solution for your problem, with the side benefit of having the option to create a logfile of what was done while in the role, although that is not a requirement.

The downside is that you will need to have multiple accounts for your users. And from a user standpoint it isn't all happening from the same process, so things like command recall, process logicals and symbols, access to their own non-privileged directory (unless allowed either by ACL or privilege in the "jumped to" username.

We use it, and it works. I would recommend at least taking a look at it.

Example:

Non-Prived user | CM role username | Admin role username

TEST1 [26,253] | TEST1_CM [31,67] | TEST1_ADMIN [32,302]

Create JUMP_ACCESS identifier (when JUMP installed)

Grant JUMP_ACCCESS to TEST1

Add a line to JUMP_ACCESS.DAT file (which is protected)

test1 : test1_cm,test1_admin : sen!i # secure, exact, all notification, don't include log in mail

Now the user test1 can enter the command

$ jump test1_admin

and they will be logged into the test1_admin username with all its access rights, go through its login.com etc, And the session will be logged (secure) and when the session is complete a message will be sent to a specified jump administrator. Optionally (we don't do this) the complete logfile can be sent with the message.

Where to get JUMP:

ftp://ftp.process.com/vms-freeware/fileserv/jump.zip
http://ftp.process.com/ftp/vms-freeware/fileserv/jump.zip

Good luck,

Jon
it depends
Oscar van Eijk
Occasional Advisor

Re: Enable/Disable dynamic identifiers in C.

Jon,

Thanks for your detailed answer. I'm sure this might work for others with a similar problem (and searching this forum :), but not for me :-/

I know JUMP, but it does not offer the option to combine environments; e.g. when a developer works on a product and needs to compile/link with a library that is not yet released, he/she needs access to the environment where that library is developed; 1 role for multiple environments....

I never said the problem is simple.... I just want a simple solution :)

Oscar
Jon Pinkley
Honored Contributor

Re: Enable/Disable dynamic identifiers in C.

Oscar,

I fail to see how the ability to turn on/off an identifier on one system will help control access on another. I am specifically referring to your mention of "CVS" and "root", which at least sound like unix to me. So if that is the case, how will an identifier on a VMS system mean anything to the unix system?

I am trying to understand the unspecified build environment you are speaking about. Is it something you have developed in-house, or is it a commercial package to has callouts to user written software (possibly the "C software" you were referring to)?

Jon
it depends
Oscar van Eijk
Occasional Advisor

Re: Enable/Disable dynamic identifiers in C.

The CVS runs on a Linux box indeed, that's not secured by de development environment, but just as the proper CMS$LIB is set when the user selects an environment, so is the correct CVS environment defined is the selected project happens to be in CVS; that's the case with Java projects.

Security is not the main issue; the dynamic identifiers are used just to create a transparent environment and prevent mistakes (not all developers are familiair with VMS).

All software is built in-house; we build and maintain it for Dutch Railways that needs to run on several VMS version, even on some good old VAXes.
"C" is just my personal choice :)