/*
- * (C) COPYRIGHT IBM CORPORATION 1987, 1988
- * LICENSED MATERIALS - PROPERTY OF IBM
+ * Copyright 2000, International Business Machines Corporation and others.
+ * All Rights Reserved.
+ *
+ * This software has been released under the terms of the IBM Public
+ * License. For details, see the LICENSE file in the top-level source
+ * directory or online at http://www.openafs.org/dl/license10.html
*/
/*
* the rpc version (via rx) of non-standard system calls. Currently only rpc
* calls of setpag, and pioctl are supported.
*/
+#include <afsconfig.h>
#include <afs/param.h>
-#include <errno.h>
+
+#include <roken.h>
+
#include <limits.h>
-#include <sys/types.h>
+
#include <afs/vice.h>
-#ifdef AFS_NT40_ENV
-#include <winsock2.h>
-#else
-#include <netdb.h>
-#include <netinet/in.h>
-#include <sys/file.h>
-#endif
-#include <sys/stat.h>
-#include <stdio.h>
#include <rx/xdr.h>
+
#include "rmtsys.h"
+#include "sys_prototypes.h"
-#define NOPAG 0xffffffff /* Also defined in afs/afs.h */
+#define NOPAG 0xffffffff /* Also defined in afs/afs.h */
static afs_int32 hostAddr = 0;
-static int hostAddrLookup = 0;
-char *afs_server=0, server_name[128];
-afs_int32 host;
-static afs_int32 SetClientCreds();
+static int hostAddrLookup = 0;
+char *afs_server = 0, server_name[128];
+static afs_int32 SetClientCreds(struct clientcred *creds, afs_uint32 * groups);
+int afs_get_pag_from_groups(afs_uint32 g0, afs_uint32 g1);
+void afs_get_groups_from_pag(afs_uint32 pag, afs_uint32 * g0p, afs_uint32 * g1p);
-/* Picks up the name of the remote afs client host where the rmtsys
+/* Picks up the name of the remote afs client host where the rmtsys
* daemon resides. Since the clients may be diskless and/or readonly
* ones we felt it's better to rely on an shell environment
* (AFSSERVER) for the host name first. If that is not set, the
* $HOME/.AFSSERVER file is checked, otherwise the "/.AFSSERVER" is
* used.
*/
-afs_int32 GetAfsServerAddr(syscall)
-char *syscall;
+afs_int32
+GetAfsServerAddr(char *syscall)
{
- register struct hostent *th;
- char *getenv();
+ struct hostent *th;
if (hostAddrLookup) {
- /* Take advantage of caching and assume that the remote host
+ /* Take advantage of caching and assume that the remote host
* address won't change during a single program's invocation.
*/
return hostAddr;
if (!(afs_server = getenv("AFSSERVER"))) {
char *home_dir;
FILE *fp;
- int len;
-
+ int len = 0;
+
if (!(home_dir = getenv("HOME"))) {
/* Our last chance is the "/.AFSSERVER" file */
fp = fopen("/.AFSSERVER", "r");
if (fp == 0) {
return 0;
}
- fgets(server_name, 128, fp);
- fclose(fp);
} else {
- char pathname[256];
+ char *pathname;
- sprintf(pathname, "%s/%s", home_dir, ".AFSSERVER");
+ len = asprintf(&pathname, "%s/%s", home_dir, ".AFSSERVER");
+ if (len < 0 || pathname == NULL)
+ return 0;
fp = fopen(pathname, "r");
+ free(pathname);
+
if (fp == 0) {
/* Our last chance is the "/.AFSSERVER" file */
fp = fopen("/.AFSSERVER", "r");
return 0;
}
}
- fgets(server_name, 128, fp);
- fclose(fp);
}
- len = strlen(server_name);
+ if (fgets(server_name, 128, fp) != NULL)
+ len = strlen(server_name);
+ fclose(fp);
if (len == 0) {
return 0;
}
- if (server_name[len-1] == '\n') {
- server_name[len-1] = 0;
+ if (server_name[len - 1] == '\n') {
+ server_name[len - 1] = 0;
}
afs_server = server_name;
}
printf("host %s not found; %s call aborted\n", afs_server, syscall);
return 0;
}
- bcopy(th->h_addr, &hostAddr, sizeof(hostAddr));
+ memcpy(&hostAddr, th->h_addr, sizeof(hostAddr));
return hostAddr;
}
/* Does the actual RX connection to the afs server */
-struct rx_connection *rx_connection(errorcode, syscall)
-afs_int32 *errorcode;
-char *syscall;
+struct rx_connection *
+rx_connection(afs_int32 * errorcode, char *syscall)
{
struct rx_connection *conn;
struct rx_securityClass *null_securityObject;
+ afs_int32 host;
if (!(host = GetAfsServerAddr(syscall))) {
*errorcode = -1;
return (struct rx_connection *)0;
- }
+ }
*errorcode = rx_Init(0);
- if(*errorcode) {
+ if (*errorcode) {
printf("Rx initialize failed \n");
return (struct rx_connection *)0;
}
null_securityObject = rxnull_NewClientSecurityObject();
- conn = rx_NewConnection(host, htons(AFSCONF_RMTSYSPORT), RMTSYS_SERVICEID, null_securityObject, 0);
+ conn =
+ rx_NewConnection(host, htons(AFSCONF_RMTSYSPORT), RMTSYS_SERVICEID,
+ null_securityObject, RX_SECIDX_NULL);
if (!conn) {
printf("Unable to make a new connection\n");
*errorcode = -1;
/* WARNING: The calling program (i.e. klog) MUST be suid-root since we need to
* do a setgroups(2) call with the new pag.... */
-#ifdef AFS_DUX40_ENV
-#pragma weak setpag = afs_setpag
-int afs_setpag()
-#else
-int setpag()
-#endif
+int
+setpag(void)
{
struct rx_connection *conn;
clientcred creds;
- afs_int32 errorcode, errornumber, newpag, ngroups, j, groups[NGROUPS_MAX];
+ afs_int32 errorcode, errornumber, newpag, ngroups, j;
+ afs_uint32 groups[NGROUPS_MAX];
if (!(conn = rx_connection(&errorcode, "setpag"))) {
/* Remote call can't be performed for some reason.
errno = errornumber;
errorcode = -1;
printf("Warning: Remote setpag to %s has failed (err=%d)...\n",
- afs_server, errno);
+ afs_server, errno);
}
if (errorcode) {
return errorcode;
/* we will have to shift grouplist to make room for pag */
if (ngroups + 2 > NGROUPS_MAX) {
/* this is what the real setpag returns */
- errno = E2BIG;
- return -1;
+ errno = E2BIG;
+ return -1;
}
for (j = ngroups - 1; j >= 0; j--) {
groups[j + 2] = groups[j];
/* Remote pioctl(2) client routine */
-#ifdef AFS_DUX40_ENV
-#pragma weak pioctl = afs_pioctl
-int afs_pioctl(path, cmd, data, follow)
-#else
-int pioctl(path, cmd, data, follow)
-#endif
-char *path;
-afs_int32 cmd, follow;
-struct ViceIoctl *data;
+int
+pioctl(char *path, afs_int32 cmd, struct ViceIoctl *data, afs_int32 follow)
{
struct rx_connection *conn;
clientcred creds;
- afs_int32 errorcode, groups[NGROUPS_MAX], errornumber, ins= data->in_size;
+ afs_int32 errorcode, errornumber, ins = data->in_size;
+ afs_uint32 groups[NGROUPS_MAX];
rmtbulk InData, OutData;
char pathname[256], *pathp = pathname, *inbuffer;
- extern char *getwd();
if (!(conn = rx_connection(&errorcode, "pioctl"))) {
/* Remote call can't be performed for some reason.
* Try the local 'pioctl' system call ... */
errorcode = lpioctl(path, cmd, data, follow);
return errorcode;
}
- (void) SetClientCreds(&creds, groups);
-#ifdef AFS_OSF_ENV
- if (!ins) ins = 1;
-#endif
- if (!(inbuffer = (char *)malloc(ins)))
- return (-1); /* helpless here */
+ (void)SetClientCreds(&creds, groups);
+ if (!(inbuffer = malloc(ins)))
+ return (-1); /* helpless here */
if (data->in_size)
- bcopy(data->in, inbuffer, data->in_size);
+ memcpy(inbuffer, data->in, data->in_size);
InData.rmtbulk_len = data->in_size;
InData.rmtbulk_val = inbuffer;
inparam_conversion(cmd, InData.rmtbulk_val, 0);
- OutData.rmtbulk_len = data->out_size;
- OutData.rmtbulk_val = data->out;
+
+ OutData.rmtbulk_len = MAXBUFFERLEN * sizeof(*OutData.rmtbulk_val);
+ OutData.rmtbulk_val = malloc(OutData.rmtbulk_len);
+ if (!OutData.rmtbulk_val) {
+ free(inbuffer);
+ return -1;
+ }
+
/* We always need to pass absolute pathnames to the remote pioctl since we
* lose the current directory value when doing an rpc call. Below we
* prepend the current absolute path directory, if the name is relative */
if (path) {
if (*path != '/') {
/* assuming relative path name */
- if (getwd(pathname) == NULL) {
+ if (getcwd(pathname, 256) == NULL) {
free(inbuffer);
- printf("getwd failed; exiting\n");
- exit(1);
- }
- strcpy(pathname+strlen(pathname), "/");
+ printf("getwd failed\n");
+ return -1;
+ }
+ strcpy(pathname + strlen(pathname), "/");
strcat(pathname, path);
} else {
strcpy(pathname, path);
* be to change the interface declartion. */
strcpy(pathname, NIL_PATHP);
}
- errorcode = RMTSYS_Pioctl(conn, &creds, pathp, cmd, follow, &InData,
- &OutData, &errornumber);
+ errorcode =
+ RMTSYS_Pioctl(conn, &creds, pathp, cmd, follow, &InData, &OutData,
+ &errornumber);
if (errornumber) {
errno = errornumber;
errorcode = -1; /* Necessary since errorcode is 0 on
* standard remote pioctl errors */
if (errno != EDOM && errno != EACCES)
printf("Warning: Remote pioctl to %s has failed (err=%d)...\n",
- afs_server, errno);
+ afs_server, errno);
}
if (!errorcode) {
/* Do the conversions back to the host order; store the results back
* on the same buffer */
- outparam_conversion(cmd, OutData.rmtbulk_val, 1);
+ if (data->out_size < OutData.rmtbulk_len) {
+ errno = EINVAL;
+ errorcode = -1;
+ } else {
+ memcpy(data->out, OutData.rmtbulk_val, data->out_size);
+ outparam_conversion(cmd, data->out, 1);
+ }
}
+ free(OutData.rmtbulk_val);
free(inbuffer);
return errorcode;
}
-
-int afs_get_pag_from_groups(g0, g1)
-afs_uint32 g0, g1;
+
+int
+afs_get_pag_from_groups(afs_uint32 g0, afs_uint32 g1)
{
- afs_uint32 h, l, result;
+ afs_uint32 h, l, result;
- g0 -= 0x3f00;
- g1 -= 0x3f00;
- if (g0 < 0xc000 && g1 < 0xc000) {
- l = ((g0 & 0x3fff) << 14) | (g1 & 0x3fff);
- h = (g0 >> 14);
- h = (g1 >> 14) + h + h + h;
- result = ((h << 28) | l);
- /* Additional testing */
- if (((result >> 24) & 0xff) == 'A')
- return result;
- else
- return NOPAG;
- }
- return NOPAG;
+ g0 -= 0x3f00;
+ g1 -= 0x3f00;
+ if (g0 < 0xc000 && g1 < 0xc000) {
+ l = ((g0 & 0x3fff) << 14) | (g1 & 0x3fff);
+ h = (g0 >> 14);
+ h = (g1 >> 14) + h + h + h;
+ result = ((h << 28) | l);
+ /* Additional testing */
+ if (((result >> 24) & 0xff) == 'A')
+ return result;
+ else
+ return NOPAG;
+ }
+ return NOPAG;
}
-
-afs_get_groups_from_pag(pag, g0p, g1p)
-afs_uint32 pag;
-afs_uint32 *g0p, *g1p;
+void
+afs_get_groups_from_pag(afs_uint32 pag, afs_uint32 * g0p, afs_uint32 * g1p)
{
- unsigned short g0, g1;
+ unsigned short g0, g1;
- pag &= 0x7fffffff;
- g0 = 0x3fff & (pag >> 14);
- g1 = 0x3fff & pag;
- g0 |= ((pag >> 28) / 3) << 14;
- g1 |= ((pag >> 28) % 3) << 14;
- *g0p = g0 + 0x3f00;
- *g1p = g1 + 0x3f00;
+ pag &= 0x7fffffff;
+ g0 = 0x3fff & (pag >> 14);
+ g1 = 0x3fff & pag;
+ g0 |= ((pag >> 28) / 3) << 14;
+ g1 |= ((pag >> 28) % 3) << 14;
+ *g0p = g0 + 0x3f00;
+ *g1p = g1 + 0x3f00;
}
-static afs_int32 SetClientCreds(creds, groups)
-struct clientcred *creds;
-afs_int32 *groups;
+static afs_int32
+SetClientCreds(struct clientcred *creds, afs_uint32 * groups)
{
afs_int32 ngroups;
creds->group0 = groups[0];
creds->group1 = groups[1];
return ngroups;
-}
+}