9408bb54e0eef4a65a73d7de2453b1d276f61005
[xscreensaver] / driver / vms-getpwnam.c
1 /*
2  *      getpwnam(name) - retrieves a UAF entry
3  *
4  *      Author:         Patrick L. Mahan
5  *      Location:       TGV, Inc
6  *      Date:           15-Nov-1991
7  *
8  *      Purpose:        Provides emulation for the UNIX getpwname routine.
9  *
10  *      Modification History
11  *
12  *      Date        | Who       | Version       | Reason
13  *      ------------+-----------+---------------+---------------------------
14  *      15-Nov-1991 | PLM       | 1.0           | First Write
15  */
16
17 #define PASSWDROUTINES
18
19 #include <stdio.h>
20 #include <descrip.h>
21 #include <uaidef.h>
22 #include <string.h>
23 #include <stdlib.h>
24 #include <starlet.h>
25 #include "vms-pwd.h"
26
27 struct uic {
28    unsigned short uid;
29    unsigned short gid;
30 };
31
32 #define TEST(ptr, str)  { if (ptr == NULL) {    \
33                                 fprintf(stderr, "getpwnam: memory allocation failure for \"%s\"\n",     \
34                                         str);   \
35                                 return ((struct passwd *)(NULL));       \
36                           } }
37
38 struct passwd *getpwnam(name)
39 char *name;
40 {
41    int  istatus;
42    int  UserNameLen;
43    int  UserOwnerLen;
44    int  UserDeviceLen;
45    int  UserDirLen;
46    static char UserName[13];
47    static char UserOwner[32];
48    static char UserDevice[32];
49    static char UserDir[64];
50    char *cptr, *sptr;
51    unsigned long int UserPwd[2];
52    unsigned short int UserSalt;
53    unsigned long int UserEncrypt;
54    struct uic UicValue;
55    struct passwd *entry;
56
57    struct dsc$descriptor_s VMSNAME = 
58         {strlen(name), DSC$K_DTYPE_T, DSC$K_CLASS_S, name};
59
60    struct itmlist3 {
61         unsigned short int length;
62         unsigned short int item;
63         unsigned long  int addr;
64         unsigned long  int retaddr;
65    } ItemList[] = {
66         {12, UAI$_USERNAME, (unsigned long)&UserName, (unsigned long)&UserNameLen},
67         {8,  UAI$_PWD, (unsigned long)&UserPwd, 0},
68         {4,  UAI$_UIC, (unsigned long)&UicValue, 0},
69         {32, UAI$_OWNER, (unsigned long)&UserOwner, (unsigned long)&UserOwnerLen},
70         {32, UAI$_DEFDEV, (unsigned long)&UserDevice, (unsigned long)&UserDeviceLen},
71         {64, UAI$_DEFDIR, (unsigned long)&UserDir, (unsigned long)&UserDirLen},
72         {2,  UAI$_SALT, (unsigned long)&UserSalt, 0},
73         {4,  UAI$_ENCRYPT, (unsigned long)&UserEncrypt, 0},
74         {0, 0, 0, 0}
75    };
76
77    UserNameLen = 0;
78    istatus = sys$getuai (0, 0, &VMSNAME, &ItemList, 0, 0, 0);
79
80    if (!(istatus & 1)) {
81 #ifdef DEBUG
82         lib$signal(istatus);
83 #endif /* DEBUG */
84         fprintf (stderr, "getpwnam: unable to retrieve passwd entry for %s\n",
85                  name);
86         fprintf (stderr, "getpwnam: vms error number is 0x%x\n", istatus);
87         return ((struct passwd *)NULL);
88    }
89
90    entry = (struct passwd *) calloc (1, sizeof(struct passwd));
91    TEST(entry, "PASSWD_ENTRY");
92
93    entry->pw_uid = UicValue.uid;
94    entry->pw_gid = UicValue.gid;
95    entry->pw_salt = UserSalt;
96    entry->pw_encrypt = UserEncrypt;
97
98    sptr = UserName;
99    cptr = calloc (UserNameLen+1, sizeof(char));
100    TEST(cptr, "USERNAME");
101    strncpy (cptr, sptr, UserNameLen);
102    cptr[UserNameLen] = '\0';
103    entry->pw_name = cptr;
104
105    cptr = calloc(8, sizeof(char));
106    TEST(cptr, "PASSWORD");
107    memcpy(cptr, UserPwd, 8);
108    entry->pw_passwd = cptr;
109
110    sptr = UserOwner; sptr++;
111    cptr = calloc ((int)UserOwner[0]+1, sizeof(char));
112    TEST(cptr, "FULLNAME");
113    strncpy (cptr, sptr, (int)UserOwner[0]);
114    cptr[(int)UserOwner[0]] = '\0';
115    entry->pw_gecos = cptr;
116
117    cptr = calloc ((int)UserDevice[0]+(int)UserDir[0]+1, sizeof(char));
118    TEST(cptr, "HOME");
119    sptr = UserDevice; sptr++;
120    strncpy (cptr, sptr, (int)UserDevice[0]);
121    sptr = UserDir; sptr++;
122    strncat (cptr, sptr, (int)UserDir[0]);
123    cptr[(int)UserDevice[0]+(int)UserDir[0]] = '\0';
124    entry->pw_dir = cptr;
125
126    cptr = calloc (strlen("SYS$SYSTEM:LOGINOUT.EXE")+1, sizeof(char));
127    TEST(cptr,"SHELL");
128    strcpy (cptr, "SYS$SYSTEM:LOGINOUT.EXE");
129    entry->pw_shell = cptr;
130
131    return (entry);
132 }