From http://www.jwz.org/xscreensaver/xscreensaver-5.27.tar.gz
[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         fprintf (stderr, "getpwnam: unable to retrieve passwd entry for %s\n",
82                  name);
83         fprintf (stderr, "getpwnam: vms error number is 0x%x\n", istatus);
84         return ((struct passwd *)NULL);
85    }
86
87    entry = (struct passwd *) calloc (1, sizeof(struct passwd));
88    TEST(entry, "PASSWD_ENTRY");
89
90    entry->pw_uid = UicValue.uid;
91    entry->pw_gid = UicValue.gid;
92    entry->pw_salt = UserSalt;
93    entry->pw_encrypt = UserEncrypt;
94
95    sptr = UserName;
96    cptr = calloc (UserNameLen+1, sizeof(char));
97    TEST(cptr, "USERNAME");
98    strncpy (cptr, sptr, UserNameLen);
99    cptr[UserNameLen] = '\0';
100    entry->pw_name = cptr;
101
102    cptr = calloc(8, sizeof(char));
103    TEST(cptr, "PASSWORD");
104    memcpy(cptr, UserPwd, 8);
105    entry->pw_passwd = cptr;
106
107    sptr = UserOwner; sptr++;
108    cptr = calloc ((int)UserOwner[0]+1, sizeof(char));
109    TEST(cptr, "FULLNAME");
110    strncpy (cptr, sptr, (int)UserOwner[0]);
111    cptr[(int)UserOwner[0]] = '\0';
112    entry->pw_gecos = cptr;
113
114    cptr = calloc ((int)UserDevice[0]+(int)UserDir[0]+1, sizeof(char));
115    TEST(cptr, "HOME");
116    sptr = UserDevice; sptr++;
117    strncpy (cptr, sptr, (int)UserDevice[0]);
118    sptr = UserDir; sptr++;
119    strncat (cptr, sptr, (int)UserDir[0]);
120    cptr[(int)UserDevice[0]+(int)UserDir[0]] = '\0';
121    entry->pw_dir = cptr;
122
123    cptr = calloc (strlen("SYS$SYSTEM:LOGINOUT.EXE")+1, sizeof(char));
124    TEST(cptr,"SHELL");
125    strcpy (cptr, "SYS$SYSTEM:LOGINOUT.EXE");
126    entry->pw_shell = cptr;
127
128    return (entry);
129 }