==Phrack Magazine==

 Volume Five, Issue Forty-Five, File 15 of 28

Some Helpful VAX/VMS utilities

Introduction

This article contains a brief introduction to some not so often used utilities, found on the Virtual Address eXtentions/ Virtual Memory System or better known to us as the VAX/VMS.

Please note that this file is meant for the so called VMS "newbies". It gives an insight to the processes that are running in the different "Hibernation" states on VMS, quite similar to the background processes running on UNIX and its clones. If you have "extensive" experience on VMS as a systems programmer or a SysOp, you might want to skip it !!

Portions of this file are taken from the ever blabbering VMS HELP, which is where many of us, myself included, learn about the VAX/VMS. VMS has lots of secrets. Locations of "hidden" files are a very well kept secret, known not even to the SysOp but only to the system programmer.

Ok.... Lets get started...

SHOW SYSTEM

This command ($Show system) will display information about the status of the processes running on the system. There are various options to this command, some of which are listed below.
    /BATCH     /CLUSTER   /FULL      /NETWORK   /NODE      /OUTPUT
    /PROCESS   /SUBPROCESS

         1.  $ SHOW SYSTEM

       VAX/VMS 5.4  on node DARTH 19-APR-1990 17:45:47.78  Uptime  2 21:53:59
         Pid    Process Name   State Pri      I/O       CPU  Page flts Ph.Mem
       27400201 SWAPPER        HIB   16        0  0 00:29:52.05      0      0
       27401E03 DOCBUILD       LEF    4    37530  0 00:05:47.62  96421    601
       27402604 BATCH_789      LEF    4     3106  0 00:00:48.67   4909   2636 B
       27401C05 BATCH_60       LEF    6      248  0 00:00:06.83   1439   1556 B
       27400207 ERRFMT         HIB    8     6332  0 00:00:41.83     89    229
       27400208 CACHE_SERVER   HIB   16     2235  0 00:00:05.85     67    202
       27400209 CLUSTER_SERVER HIB    8     4625  0 00:22:13.28    157    448
       2740020C JOB_CONTROL    HIB   10   270920  0 01:07:47.88   5163   1384
       2740020D CONFIGURE      HIB    9      125  0 00:00:00.53    104    264
        .
        .
        .
       27400E8D Sir Lancelot   LEF    5      226  0 00:00:07.87   4560    697
       2740049A Guenevere      LEF    4      160  0 00:00:02.69    534    477
       27401EA0 BATCH_523      CUR  4 4    17470  0 03:25:49.67   8128   5616 B
       274026AF GAWAIN         CUR  6 4    14045  0 00:02:03.24  20032    397
       274016D5 GAHERIS        LEF    6      427  0 00:00:09.28   5275   1384
       27401ED6 knight_1       HIB    5      935  0 00:00:10.17   3029   2204 S
       274012D7 BATCH_689      LEF    4    49216  0 00:14:18.36   7021   3470 B
       274032D9 DECW$MAIL      LEF    4     2626  0 00:00:51.19   4328   3087 B
       274018E3 SERVER_0021    LEF    6      519  0 00:00:07.07   1500    389 N
       274016E8 NMAIL_0008     HIB    4    10955  0 00:00:55.73   5652    151
       274034EA MORDRED        LEF    4     2132  0 00:00:23.85   5318    452
       274022EB S. Whiplash    CUR  6 4      492  0 00:00:12.15   5181    459
       274018EF DwMail         LEF    5   121386  0 00:28:00.97   7233   4094
       27401AF0 EMACS$RTA43    LEF    4    14727  0 00:03:56.54   8411   4224 S
       27400CF4 TRISTRAM       HIB    5    25104  0 00:06:07.76  37407   1923
       274020F5 Morgan         LEF    7    14726  0 00:02:10.74  34262   1669
       27400CF6 mr. mike       LEF    9    40637  0 00:05:15.63  18454    463
The information in this example includes the following:
         2.  $ SHOW SYSTEM /CLUSTER


       VAX/VMS V5.4 on node APPLE 19-APR-1990 09:09:58.61  Uptime    0 2:27:11
       Pid       Process Name   State  Pri I/O  CPU           Page flts Ph. Mem
       31E00041  SWAPPER        HIB    16    0  0 00:00:02.42     0       0
       31E00047  CACHE_SERVER   HIB    16   58  0 00:00:00.26    80      36
       31E00048  CLUSTER_SERVER CUR     9  156  0 00:00:58.15  1168      90
       31E00049  OPCOM          HIB     7 8007  0 00:00:33.46  5506     305
       31E0004A  AUDIT_SERVER   HIB     9  651  0 00:00:21.17  2267      22
       31E0004B  JOB_CONTROL    HIB    10 1030  0 00:00:11.02   795     202
          .
          .
          .
The SHOW SYSTEM command in this example shows all processes on all nodes of the cluster.
         3.  $ SHOW SYSTEM /NODE=NEON
       VAX/VMS V5.4 on node NEON 19-APR-1990 09:19:15.33  Uptime    0 02:29:07
       Pid       Process Name   State  Pri  I/O  CPU           Page flts Ph. Mem
       36200041  SWAPPER        HIB    16     0  0 00:00:12.03     0       0
       36200046  ERRFMT         HIB     8   263  0 00:00:05.89   152      87
       36200047  CACHE_SERVER   CUR    16     9  0 00:00:00.26    80      51
       36200048  CLUSTER_SERVER CUR     8    94  0 00:00:30.07   340      68
       36200049  OPCOM          HIB     6  2188  0 00:02:01.04  1999     177
       3620004A  AUDIT_SERVER   HIB    10   346  0 00:00:10.42  1707      72
          .
          .
          .
The SHOW SYSTEM command in this example shows all processes on the node NEON.

So now that we beat the SHOW SYSTEM command to death, lets take on another command. Hmmm..let's see..Ahhhaaaa the MONITOR SYSTEM !!!!!

This is a pretty neat command and one of my favorite "play" commands. Don't get me wrong, there's a lot to be learned from "play" commands like these. It really gives us some useful information. The reason why I like this utility is because it gives a GRAPHICAL representation of the data given by the SHOW SYSTEM. I would have included a short example of the graphics, but not everyone receiving this article would be running VMS on a terminal with ANSI emulation. So, if you want to see the ANSI graphics, follow my instructions...

MONITOR

Invokes the VMS Monitor Utility (MONITOR) to monitor classes of system-wide performance data at a specified interval. It produces three types of optional output: You can collect data from a running system or from a previously created recording file.

You can execute a single MONITOR request, or enter MONITOR interactive mode to execute a series of requests. Interactive mode is entered when the MONITOR command is issued with no parameters or qualifiers.

A MONITOR request can be terminated by pressing CTRL/C or CTRL/Z. CTRL/C causes MONITOR to enter interactive mode; CTRL/Z returns to DCL.

The MONITOR Utility is described in detail in the VMS Monitor Utility Manual.

Format: MONITOR class-name[,...]

There are quite a few different options available for the MONITOR utility. We are not going to get into too much detail about each option, but I will take the time to discuss a few. The different options for MONITOR are....

  ALL_CLASSES           CLUSTER    DECNET     DISK       DLOCK      FCP
  FILE_SYSTEM_CACHE     IO         LOCK       MODES      MSCP_SERVER
  PAGE       POOL       PROCESSES  RMS        SCS        STATES     SYSTEM
  TRANSACTION           VECTOR
  /BEGINNING /BY_NODE   /COMMENT   /DISPLAY   /ENDING    /FLUSH_INTERVAL
  /INPUT     /INTERVAL  /NODE      /RECORD    /SUMMARY   /VIEWING_TIME
  /ALL       /AVERAGE   /CPU       /CURRENT   /FILE      /ITEM      /MAXIMUM
MONITOR Parameter class-name[,...]

Specifies one or more classes of performance data to be monitored. The available class-names are:

          ALL_CLASSES       All MONITOR classes.
          CLUSTER           Cluster wide information.
          DECNET            DECnet-VAX statistics.
          DISK              Disk I/O statistics.
          DLOCK             Distributed lock management statistics
          FCP               File system primitive statistics.
          FILE_SYSTEM_CACHE File system caching statistics.
          IO                System I/O statistics.
          LOCK              Lock management statistics.
          MODES             Time spent in each of the processor modes.
          MSCP_SERVER       MSCP Server statistics
          PAGE              Page management statistics.
          POOL              Space allocation in the nonpaged dynamic pool.
          PROCESSES         Statistics on all processes.
          RMS               VMS Record Management Services statistics
          SCS               System communication services statistics.
          STATES            Number of processes in each scheduler state.
          SYSTEM            System statistics.
          TRANSACTION       DECdtm services statistics.
          VECTOR            Vector Processor scheduled usage.
MONITOR /ALL

Specifies that a table of current, average, minimum, and maximum statistics is to be included in display and summary output.

/ALL is the default for all class-names except MODES, STATES and SYSTEM. It may not be used with the PROCESSES class-name.

Well, I hope this little file helps a few people out, by providing them with a better understanding of the background processes running on the system and by providing a better perception of the amount of CPU and I/O time taken by each process.

DARTH VADER

P.S : Look for a file on ACL (Access Control Listing) in the near future.

------------------------------------------------------------------------------

VAX/VMS AUTHORIZATION SYSTEM

Introduction

Well, since Phrack issues containing VMS articles are pretty rare I will examine in deep the authorization sub-system on VAXes.

Keep in mind that I will take under consideration that you are probably under some new VMS version (5.5-X). If you are on some older VMS, don't worry, commands are the same, just some flags and display was added on later versions. The knowledge of the authorization sub-system is of great importance for a VAX hacker since he must keep himself an access to the system, and this is the right way to do it.

Also keep in mind that this is just a practical guide oriented to a hacker's needs and was done to be understandable by and useable by everybody, even those who are not so familiar with VMS. That's why I included some references to VMS filesystem, privileges, etc.

AUTHORIZE

The authorization subsystem is the one that will let you create accounts under the VMS operating system. The command you need to execute is the:

SYS$SYSTEM:AUTHORIZE.EXE

What do you need to execute that program ?

READ/WRITE PRIVS over SYSUAF.DAT EXECUTE PRIVS over SYS$SYSTEM:AUTHORIZE.EXE

How can you check if you got all needed to start creating accounts ?

DIR SYS$SYSTEM:AUTHORIZE.EXE/FULL
Directory SYS$SYSROOT:[SYSEXE] <----- Directory you are listing
AUTHORIZE.EXE;1               File ID:  (2491,5,0)
Size:          164/165        Owner:    [SYSTEM] <---- Owner is Sys Manager
Created:  20-JUL-1990 08:30:34.18  <------- Creation Date of program
Revised:  17-AUG-1992 09:45:36.31 (4) <------ Last modification over program
Expires:   <None specified>    <---- No expiration, will last for ever
Backup:    <No backup recorded>
File organization:  Sequential
File attributes:    Allocation: 165, Extend: 0, Global buffer count: 0
                    No version limit, Contiguous best try
Record format:      Fixed length 512 byte records <--- record organization
Record attributes:  None
RMS attributes:     None
Journaling enabled: None
File protection:    System:RWED, Owner:RWED, Group:R, World: <---- (*)
Access Cntrl List:  None
Total of 1 file, 164/165 blocks.
(*) This is the field that will tell if you are authorized to execute the program. In this case if you own a privileged account you can run it. That doesn't mean that you will be able to view/modify any account found on the SYSUAF.DAT. But 95 % of the time any user can execute the AUTHORIZE program even if you don't have READ privilege on the SYS$SYSTEM directory. That means that if you do a :

DIR SYS$SYSTEM

and you find that you don't have the privilege to view the files contained in that directory you may still be able to execute the AUTHORIZATION subsystem, of course, you have a real low chance of getting the SYSUAF.DAT read or modified.

If you find that the authorize program cannot be executed a good method is to send it UUENCODED from another VAX where you *DO* have at least read access to SYS$SYSTEM:AUTHORIZE.EXE . If you are working on the X-25's you can send it via PSI mailing. If you are on the Internet, just send it using the normal mail routing method to the user on the VAX you want the AUTHORIZE.EXE to get executed by. Once you get it just UUDECODE it and place it in your SYS$LOGIN directory and execute it!.

The authorize will work as a module, and won't try to overlay any other module to make it work correctly. If you can run the authorize you should receive :

"UAF>" prompt.

THE SYSUAF.DAT

The SYSUAF.DAT is the most important file of the authorization subsystem. All the accounts are stored here with their : ... and more

The SYSUAF.DAT is somehow like the /etc/passwd file on Unix OS. Under UNIX you can take the password file and with an editor add yourself an account or modify an existing one without problem. Well this is not possible under VMS. You need a program that knows SYSUAF.DAT record structure (like AUTHORIZE) to take action over accounting system.

The main difference is that the SYSUAF.DAT is not a PLAIN TEXT FILE, its a binary file structured to be read only by the AUTHORIZE program. Another main difference is that is not world readable, can usually be only read from high privileged accounts or from accounts which can override system protection flags (will talk about this later).

The SYSUAF.DAT can be found in the same directory as the AUTHORIZE.EXE program, the SYS$SYSTEM. You will usually find a few versions of this file but normally with the same protections as the working one. What can be interesting is that you can usually find files produced by the output of the LIST command (under AUTHORIZE) which can be WORLD readable where you will have all the accounts listed with the OWNER/DIR/PRIVS..etc. That will help you a lot to try to hack some accounts if you still can't run authorize. Those files are called normally: SYSUAF.LIS, and you might find more than just one of them. Of course try to get the latest one since the older ones will contain some expired/deleted accounts.

To check what privilege you have over the SYSUAF.DAT issue :

DIR SYS$SYSTEM:SYSUAF.DAT/FULL

Directory SYS$COMMON:[SYSEXE]
SYSUAF.DAT;1                  File ID:  (228,1,0)
Size:          183/183        Owner:    [SYSTEM]
Created:  20-JUL-1990 08:30:21.50
Revised:  14-JAN-1994 03:33:27.75 (34812) <--- Last Creation/Modification
Expires:   <None specified>
Backup:    <No backup recorded>
File organization:  Indexed, Prolog: 3, Using 4 keys
                             In 3 areas
File attributes:    Allocation: 183, Extend: 3, Maximum bucket size: 3
                    Global buffer count: 0, No version limit
                    Contiguous best try
Record format:      Variable length, maximum 1412 bytes
Record attributes:  None
RMS attributes:     None
Journaling enabled: None
File protection:    System:RWED, Owner:RWED, Group:R, World: (*)
Access Cntrl List:  None

Total of 1 file, 183/183 blocks.
In this case, if you are under a standard user account you won't be able to READ or/and WRITE the SYSUAF.DAT. So when you will execute the AUTHORIZE program, it will quit and kick you back to shell. IF you have World : R, you will be able to LIST/SHOW accounts. IF you have World : RW, you will be able to CREATE/MODIFY accounts.

But if you happen to have SYSPRIV you will be able CREATE/MODIFY the SYSUAF.DAT at your pleasure! Since you can override the system protection that has been imposed over that file. Of course, if you have SETPRV privilege you have ALL privilege, and you can do whatever you want with the VAX.

Privileges needed to CREATE/MODIFY accounts :

Process privileges:

Entering AUTHORIZE

Once you've executed AUTHORIZE you will receive its main prompt:

RUN SYS$SYSTEM:AUTHORIZE

UAF>

UAF stands for User Authorization File.

First of all you will first need to get a list of all the accounts on the system with some of their settings also. To do this issue the command:

UAF>SHOW USERS/BRIEF

       Owner         Username           UIC       Account  Privs Pri Directory

ALLIN1V24CREATED     A1$XFER_IN      [660,1]               Normal  4 Disuser
ALLIN1V24CREATED     A1$XFER_OUT     [660,2]               Normal  4 Disuser
JOHN_FAVORITE        JFAVORITE       [300,2]      LEDGER   Devour  4 DEV$DUA2
:[ABDURAHMAN]

IBRAHIM ALBHIR       ALBHIR           [60,111]    GOTVOT   Normal  4 DUA2:[ALB
HIR]

ALGHAMDI             ALGHAMDI        [300,1]      LEDGER   Normal  4 DUA2:[ALG
HAMDI]

ALHAJAJ              ALHAJAJ         [325,3]      BUDGET   Devour  4 GOTDEV$DU
A2
Explanation:
  1. Owner: Owner of the account
  2. Username: This is the guy's login name
  3. UIC: User Identification Code. This serves to the OS to recognize you and rights you have over files, directory, etc.
  4. Account: This is to let the operator know what the group is that owns/manages the account.
  5. Pri: don't worry about it.
  6. Directory: This is the account HOME directory. Where the owner of the account will work on.
After you have captured the output of the SHOW command you can start trying to create yourself some accounts by modifying some already existing ones (which I suggest strongly).

To create an account issue the following command :

CREATE JOHN/DIR=JOHNS_DIR/DEVICE=SYS$USER/PASSWORD=JOHNS_PASSWORD
/ACCESS=(DIALUP,NETWORK)/PRIVS=(NETMBX,TMPMBX)/DEFPRIVS=(NETMBX,TMPMBX)
/ACCOUNT=USERS/OWNER=JOHN
Effects of this command:

Will create a user called JOHN which will log under the JOHNS_DIR directory, who will have just normal user privileges (TMPMBX/NETMBX) who, when listed, will appear to be as part of the group name USERS and the account's owner will be JOHN.

After you issue this command a NEW UIC will be added to the RIGHTSLIST.DAT file being assigned to your user.

Explanation:

Tips to create accounts

First of all, what I suggest strongly is to MODIFY accounts not to CREATE new ones. Why this? Well, new account names can jump out at the operator and he will kick you off the system very soon.

The best way I think is to get a non-used account, change its privileges and change the password and use it!.

First of all try to find a never-logged account or at least one account whose last log comes from few months ago. From the UAF prompt just do a SH USER/FULL and check out the dates that appear in the *Last Login* record. If this happens to be a very old one then it can be marked as valid to take control of. Of course you have to find a non used account since you will have to change the account's password.

Check the flags field also. This flags can really bother you:

I suggest you take out all the flag's fields. just issue: MODIFY JOHN/FLAGS=(NOCAPTIVE,NOCTLY,NORESTRICED,NODISUSER) If you find an account that is DisUser I suggest not to own it since the DisUser flags will take on when listing the accounts. If system manager sees an account that was OFF now ON..well it's a bit suspicious don't you think ?

Check if the FIELD account is being used. If not own this one since it already has ALL privileges and will not look suspicious at all. Just change its password. (FIELD is the account normally used by Digital Engineers to check the VAX).

Remember to check also that DIALUP access is permitted or you won't be able to login your account.

Once you've chosen the perfect account you can now change its password. Issue: MODIFY JOHN/PASSWORD=MY_PASSWORD. (John is the account name you found)

After you finished just type CTRL-Z and to exit. If you happen to logoff without exiting AUTHORIZE, don't worry. Changes to SYSUAF.DAT are done instantly when the command finishes its execution.

One other advice, under SHELL if you happen to have SECURITY privilege Issue: SET AUDIT/ALARM/DISABLE=(AUTHORIZE)

If you don't do this, each time you run AUTHORIZE, modified accounts will be logged into OPERATOR.LOG so remember to do so.

After playing a bit with AUTHORIZE you won't have much problems understanding it. Hope you have PHUN! ;-)

------------------------------------------------------------------------------
$ ! FACILITY: Mailback     (MAILBACK.COM)
$ !
$ ! ABSTRACT: VAXVMS to VAXVMS file transfer, using the VAX/PSI_MAIL
$ !           utility of VAXPSI, over an X.25 link.
$ !
$ ! ENVIRONMENT: VAX/VMS operating system.
$ !
$! -------------------------------------------------------------------
$ saved_verify := 'f$verify(0)'
$ set noon
$ ws = "write sys$output"
$ ws ""
$ ws "   MAILBACK transfer utility V1.0 (via Backup and PSI_Mail) 21-May-1990"
$ ws ""
$!
$ if f$logical("debug").nes."" then set verify
$ ask_p1:
$ if P1.eqs."" then read/prompt="MailBack> Send or Receive (S/R) : " -
                    sys$command P1
$ P1 = f$edit(P1, "UPCASE,COMPRESS,TRIM")
$!
$!
$ if P1.EQS."" then exit 1+0*f$verify(saved_verify)
$ if P1.EQS."R" then goto receive_file
$ if P1.nes."S" then goto ask_P1
$! -------------------------------------------------------------------
$!
$! Sending File(s)
$! ===============
$ if P2.eqs. "" then -
     read/prompt="MailBack> Recipient mail address (PSI%nnn::user) : " -
     sys$command P2
$ if P2.eqs."" then exit 1+0*f$verify(saved_verify)
$!
$!
$ if P3.eqs."" then read/prompt="MailBack> File(s) : " sys$command P3
$!
$ ws "MailBack> ... Backuping the file(s) ..."
$ Backup/nolog 'P3' sys$scratch:mailbck.tmp/sav/block=2048
$!
$ ws "MailBack> ... Converting format ..."
$ convert/fdl=sys$input sys$scratch:mailbck.tmp sys$scratch:mailbck.tmp
record
 carriage_control carriage_return
$!
$ ws "MailBack> ... Sending a (PSI_)mail ..."
$ on warning then goto error_sending
$ mail/subject="MAILBACK Backup-File" -
      /noself sys$scratch:mailbck.tmp 'P2'
$ ws "MailBack> ... SEND command SUCCESSfully completed."
$!
$ fin_send:
$ delete = "delete"
$ delete/nolog/noconfirm sys$scratch:mailbck.tmp;,;
$ exit  1+0*f$verify(saved_verify)
$!
$ Error_sending:
$ ws "MailBack> Error detected while sending the mail ; ..."
$ ws "MailBack> ... Fix the problem, then retry the whole procedure."
$ goto fin_send
$! -------------------------------------------------------------------
$!
$! Inbound File(s) Processing
$! ==========================
$receive_file:
$!
$ if P2.eqs."" then -
     read/prompt="MailBack> Destination directory (<CR>= []) : " sys$command P2
$ if P2.eqs."" then p2 ="[]"
$!
$!
$!
$ if P3.eqs."" then -
     read/prompt="MailBack> Mail file (<CR>= default mail file) : " -
     sys$command P3
$ gosub build_file
$ ws "MailBack> ... Extracting a (PSI_)mail from the NEWMAIL folder ..."
$ define/exec sys$output nl:            ! ped 18-May-90 (wipe out mail displays)

$ if P3.eqs."" then goto normal_get
$ define/nolog new_mail_file 'p3'
$ define/user sys$command sys$input
$ set message/nofacility/noseverity/notext/noident
$ mail
set file new_mail_file
select NEWMAIL
sear MAILBACK Backup-File
extract/NOHEADER out_file
$ deassign new_mail_file
$ goto clean
$ if P3.nes."" then p2 ="[]"
$!
$!
$ normal_get:
$ define/user sys$command sys$input
$ set message/nofacility/noseverity/notext/noident
$ mail
select NEWMAIL
sear MAILBACK Backup-File
extract/NOHEADER out_file
$!
$ clean:
$ deassign sys$output                           !
$ set message/facility/severity/text/ident
$ if f$search("out_file") .eqs. "" then goto nomessage
$ on warning then goto error_conv
$ ws "MailBack> ... Converting format ..."
$ convert/fdl=sys$input out_file out_file /pad=%x00
 record
 format fixed
 carriage_control none
 size 2048
$!
$ ws "MailBack> ... Restoring file(s) from the backup saveset ..."
$ on warning then goto error_back
$ backup/nolog out_file/save 'P2'*.*
$!
$ delete = "delete"
$ delete/nolog/noconfirm  'file';,;
$ ws "MailBack> ... RECEIVE command SUCCESSfully completed."
$!
$ finish_r:
$ deassign out_file
$ exit  1+0*f$verify(saved_verify)
$! -------------------------------------------------------------------
$ error_conv:
$ ws "MailBack> " + -
     "An error occurred during the fdl convert of the extracted mail ;"
$ ws "MailBack> ... the file ''file' corresponds to " + -
$ ws "MailBack> ... the message extracted from Mail."
$ goto finish_r
$!
$ error_back:
$ ws "MailBack> An error occurred during the file restore phase with BACKUP ;"
$ ws "MailBack> ... the file ''file' corresponds to "
$ ws "MailBack> " + -
     "... the  message extracted from Mail, converted as a backup Saveset."
$ delete/nolog/noconfirm  'file';-1
$ goto finish_r
$!
$ nomessage:
$ ws "MailBack> No mail message has been found in the NEWMAIL folder."
$ goto finish_r
$!
$Build_file:                    ! Build a unique (temporary) file_name
$file = "sys$scratch:mail_" + f$cvtime(f$time(),,"month")+ -
f$cvtime(f$time(),,"day") + f$cvtime(f$time(),,"hour")+ -
f$cvtime(f$time(),,"minute")+ f$cvtime(f$time(),,"second") + ".tmp"
$define/nolog out_file 'file'
$return