/*
- * $Id: auth.c,v 1.31 2002-10-11 17:07:19 didg Exp $
+ * $Id: auth.c,v 1.32 2002-10-12 04:02:46 didg Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
#ifdef WITH_CATSEARCH
uam_afpserver_action(AFP_CATSEARCH_EXT, UAM_AFPSERVER_POSTAUTH, afp_catsearch, NULL);
#endif
+ uam_afpserver_action(AFP_GETSESSTOKEN, UAM_AFPSERVER_POSTAUTH, afp_getsession, NULL);
+ uam_afpserver_action(AFP_DISCTOLDSESS, UAM_AFPSERVER_POSTAUTH, afp_disconnect, NULL);
uam_afpserver_action(AFP_ENUMERATE_EXT, UAM_AFPSERVER_POSTAUTH, afp_enumerate, NULL);
uam_afpserver_action(AFP_READ_EXT, UAM_AFPSERVER_POSTAUTH, afp_read_ext, NULL);
uam_afpserver_action(AFP_WRITE_EXT, UAM_AFPSERVER_POSTAUTH, afp_write_ext, NULL);
return( AFP_OK );
}
-int afp_login(obj, ibuf, ibuflen, rbuf, rbuflen )
+/* ---------------------- */
+int afp_getsession(obj, ibuf, ibuflen, rbuf, rbuflen )
+AFPObj *obj;
+char *ibuf, *rbuf;
+unsigned int ibuflen, *rbuflen;
+{
+ u_int16_t type;
+ u_int32_t idlen;
+
+ u_int32_t tklen;
+ pid_t token;
+
+ *rbuflen = 0;
+
+ ibuf++;
+ ibuflen--;
+
+ memcpy(&type, ibuf, sizeof(type));
+ type = ntohs(type);
+ ibuf += sizeof(type);
+ ibuflen -= sizeof(type);
+ /*
+ *
+ */
+ switch (type) {
+ case 0: /* old version ?*/
+ break;
+ case 1: /* disconnect */
+ case 2: /* reconnect update id */
+ if (ibuflen >= sizeof(idlen)) {
+ memcpy(&idlen, ibuf, sizeof(idlen));
+ idlen = ntohl(idlen);
+ ibuf += sizeof(idlen);
+ ibuflen -= sizeof(idlen);
+ if (ibuflen < idlen) {
+ return AFPERR_PARAM;
+ }
+ /* memcpy (id, ibuf, idlen) */
+ }
+ break;
+ }
+ *rbuflen = sizeof(type);
+ type = htons(type);
+ memcpy(rbuf, &type, sizeof(type));
+ rbuf += sizeof(type);
+
+ *rbuflen += sizeof(tklen);
+ tklen = htonl(sizeof(pid_t));
+ memcpy(rbuf, &tklen, sizeof(tklen));
+ rbuf += sizeof(tklen);
+
+ *rbuflen += sizeof(pid_t);
+ token = getpid();
+ memcpy(rbuf, &token, sizeof(pid_t));
+ return AFP_OK;
+}
+
+/* ---------------------- */
+int afp_disconnect(obj, ibuf, ibuflen, rbuf, rbuflen )
AFPObj *obj;
char *ibuf, *rbuf;
int ibuflen, *rbuflen;
{
- struct passwd *pwd = NULL;
- int len, i, num;
+ u_int16_t type;
+
+ u_int32_t tklen;
+ pid_t token;
*rbuflen = 0;
+ ibuf++;
+ memcpy(&type, ibuf, sizeof(type));
+ type = ntohs(type);
+ ibuf += sizeof(type);
- if ( nologin & 1)
- return send_reply(obj, AFPERR_SHUTDOWN );
+ memcpy(&tklen, ibuf, sizeof(tklen));
+ tklen = ntohl(tklen);
+ ibuf += sizeof(tklen);
- if (ibuflen <= 1)
- return send_reply(obj, AFPERR_BADVERS );
+ if (tklen != sizeof(pid_t)) {
+ return AFPERR_MISC;
+ }
+ memcpy(&token, ibuf, tklen);
+ /* killed old session, not easy */
+ return AFP_OK;
+}
- ibuf++;
- len = (unsigned char) *ibuf++;
+/* ---------------------- */
+static int get_version(obj, ibuf, ibuflen, len)
+AFPObj *obj;
+char *ibuf;
+int ibuflen;
+int len;
+{
+ int num,i;
- ibuflen -= 2;
if (!len || len > ibuflen)
- return send_reply(obj, AFPERR_BADVERS );
+ return AFPERR_BADVERS;
num = sizeof( afp_versions ) / sizeof( afp_versions[ 0 ]);
for ( i = 0; i < num; i++ ) {
}
}
if ( i == num ) /* An inappropo version */
- return send_reply(obj, AFPERR_BADVERS );
+ return AFPERR_BADVERS ;
if (afp_version >= 30 && obj->proto != AFPPROTO_DSI)
+ return AFPERR_BADVERS ;
+
+ return 0;
+}
+
+/* ---------------------- */
+int afp_login(obj, ibuf, ibuflen, rbuf, rbuflen )
+AFPObj *obj;
+char *ibuf, *rbuf;
+int ibuflen, *rbuflen;
+{
+ struct passwd *pwd = NULL;
+ int len, i;
+
+ *rbuflen = 0;
+
+ if ( nologin & 1)
+ return send_reply(obj, AFPERR_SHUTDOWN );
+
+ if (ibuflen <= 1)
return send_reply(obj, AFPERR_BADVERS );
+ ibuf++;
+ len = (unsigned char) *ibuf++;
+ ibuflen -= 2;
+
+ i = get_version(obj, ibuf, ibuflen, len);
+ if (i)
+ return send_reply(obj, i );
+
ibuf += len;
ibuflen -= len;
return send_reply(obj, login(obj, pwd, afp_uam->u.uam_login.logout));
}
+/* ---------------------- */
+int afp_login_ext(obj, ibuf, ibuflen, rbuf, rbuflen )
+AFPObj *obj;
+char *ibuf, *rbuf;
+int ibuflen, *rbuflen;
+{
+ struct passwd *pwd = NULL;
+ int len, i;
+ char type;
+/*
+ u_int16_t h;
+*/
+ *rbuflen = 0;
+
+ if ( nologin & 1)
+ return send_reply(obj, AFPERR_SHUTDOWN );
+
+ if (ibuflen <= 2)
+ return send_reply(obj, AFPERR_BADVERS );
+
+ ibuf++;
+ ibuf++; /* flag */
+ len = (unsigned char) *ibuf++;
+ ibuflen -= 3;
+
+ i = get_version(obj, ibuf, ibuflen, len);
+ if (i)
+ return send_reply(obj, i );
+
+ ibuf += len;
+ ibuflen -= len;
+
+ if (ibuflen <= 1)
+ return send_reply(obj, AFPERR_BADUAM);
+
+ len = (unsigned char) *ibuf++;
+ ibuflen--;
+
+ if (!len || len > ibuflen)
+ return send_reply(obj, AFPERR_BADUAM);
+
+ if ((afp_uam = auth_uamfind(UAM_SERVER_LOGIN, ibuf, len)) == NULL)
+ return send_reply(obj, AFPERR_BADUAM);
+ ibuf += len;
+ ibuflen -= len;
+
+ /* FIXME user name */
+ if (len <= 1)
+ return send_reply(obj, AFPERR_PARAM);
+ type = *ibuf;
+ ibuf++;
+ ibuflen--;
+
+ i = afp_uam->u.uam_login.login(obj, &pwd, ibuf, ibuflen, rbuf, rbuflen);
+ if (i || !pwd)
+ return send_reply(obj, i);
+
+ return send_reply(obj, login(obj, pwd, afp_uam->u.uam_login.logout));
+}
+/* ---------------------- */
int afp_logincont(obj, ibuf, ibuflen, rbuf, rbuflen)
AFPObj *obj;
char *ibuf, *rbuf;
/*
- * $Id: auth.h,v 1.2 2001-06-20 18:33:04 rufustfirefly Exp $
+ * $Id: auth.h,v 1.3 2002-10-12 04:02:46 didg Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
/* FP functions */
extern int afp_login __P((AFPObj *, char *, int, char *, int *));
+extern int afp_login_ext __P((AFPObj *, char *, int, char *, int *));
extern int afp_logincont __P((AFPObj *, char *, int, char *, int *));
extern int afp_changepw __P((AFPObj *, char *, int, char *, int *));
extern int afp_logout __P((AFPObj *, char *, int, char *, int *));
extern int afp_getuserinfo __P((AFPObj *, char *, int, char *, int *));
+extern int afp_getsession __P((AFPObj *, char *, unsigned int, char *, unsigned int *));
+extern int afp_disconnect __P((AFPObj *, char *, int, char *, int *));
#endif /* auth.h */
/*
- * $Id: directory.c,v 1.42 2002-10-11 14:18:27 didg Exp $
+ * $Id: directory.c,v 1.43 2002-10-12 04:02:46 didg Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
char *u;
int extend = 0;
int len;
- int olen = 0;
-
+ int olen = 0;
+ u_int32_t hint;
+ int size = 0;
+ char sep;
+
data = *cpath;
- if ( *data++ != 2 ) { /* path type */
+ switch (*data) { /* path type */
+ case 2:
+ data++;
+ len = (unsigned char) *data++;
+ size = 2;
+ sep = 0;
+ break;
+ case 3:
+ if (afp_version >= 30) {
+ data++;
+ hint = ntohl(*data);
+ data += 4;
+ len = ntohs(*data);
+ data += 2;
+ size = 7;
+ sep = '/';
+ break;
+ }
+ /* else it's an error */
+ default:
return( NULL );
+
}
- len = (unsigned char) *data++;
- *cpath += len + 2;
+ *cpath += len + size;
*path = '\0';
u = NULL;
ret.m_name = path;
}
u = NULL;
- while ( *data == '\0' && len > 0 ) {
+ while ( *data && *data == sep && len > 0 ) {
if ( dir->d_parent == NULL ) {
return NULL;
}
u = data;
olen = len;
}
- while ( *data != '\0' && len > 0 ) {
+ while ( *data && *data != sep && len > 0 ) {
*p++ = *data++;
len--;
}
(".", curdir)
(name, dir) with curdir:name == dir, from afp_enumerate
*/
+
int getdirparams(const struct vol *vol,
u_int16_t bitmap, struct path *s_path,
struct dir *dir,
int bit = 0, isad = 0;
u_int32_t aint;
u_int16_t ashort;
- int ret;
+ int ret;
+ u_int32_t utf8 = 0;
struct stat *st = &s_path->st;
char *upath = s_path->u_name;
/* Client has requested the ProDOS information block.
Just pass back the same basic block for all
directories. <shirsch@ibm.net> */
- case DIRPBIT_PDINFO : /* ProDOS Info Block */
- *data++ = 0x0f;
- *data++ = 0;
- ashort = htons( 0x0200 );
- memcpy( data, &ashort, sizeof( ashort ));
- data += sizeof( ashort );
- memset( data, 0, sizeof( ashort ));
- data += sizeof( ashort );
+ case DIRPBIT_PDINFO :
+ if (afp_version >= 30) { /* UTF8 name */
+ utf8 = kTextEncodingUTF8;
+ if (dir->d_m_name) /* root of parent can have a null name */
+ nameoff = data;
+ else
+ memset(data, 0, sizeof(u_int16_t));
+ data += sizeof( u_int16_t );
+ }
+ else { /* ProDOS Info Block */
+ *data++ = 0x0f;
+ *data++ = 0;
+ ashort = htons( 0x0200 );
+ memcpy( data, &ashort, sizeof( ashort ));
+ data += sizeof( ashort );
+ memset( data, 0, sizeof( ashort ));
+ data += sizeof( ashort );
+ }
break;
default :
if ( nameoff ) {
ashort = htons( data - buf );
memcpy( nameoff, &ashort, sizeof( ashort ));
-
- if ((aint = strlen( dir->d_m_name )) > MACFILELEN)
- aint = MACFILELEN;
-
- *data++ = aint;
- memcpy( data, dir->d_m_name, aint );
- data += aint;
+ data = set_name(data, dir->d_m_name, utf8);
}
if ( isad ) {
ad_close( &ad, ADFLAGS_HF );
ProDOS information block. Skip over the data and
report nothing amiss. <shirsch@ibm.net> */
case DIRPBIT_PDINFO :
- buf += 6;
- break;
-
+ if (afp_version < 30) {
+ buf += 6;
+ break;
+ }
default :
err = AFPERR_BITMAP;
goto setdirparam_done;
char *name;
u_int32_t id;
int len, sfunc;
-
+ int utf8 = 0;
+
ibuf++;
sfunc = (unsigned char) *ibuf++;
memcpy( &id, ibuf, sizeof( id ));
if ( id != 0 ) {
switch ( sfunc ) {
case 1 :
+ case 3 :/* unicode */
if (( pw = getpwuid( id )) == NULL ) {
*rbuflen = 0;
return( AFPERR_NOITEM );
break;
case 2 :
+ case 4 : /* unicode */
if (( gr = (struct group *)getgrgid( id )) == NULL ) {
*rbuflen = 0;
return( AFPERR_NOITEM );
*rbuflen = 0;
return( AFPERR_PARAM );
}
-
+ switch ( sfunc ) {
+ case 3:
+ case 4:
+ if (afp_version < 30) {
+ *rbuflen = 0;
+ return( AFPERR_PARAM );
+ }
+ utf8 = 1;
+ /* map to unicode */
+ break;
+ }
len = strlen( name );
} else {
len = 0;
name = NULL;
}
-
- *rbuf++ = len;
+ if (utf8) {
+ u_int16_t tp = htons(len);
+ memcpy(rbuf, &tp, sizeof(tp));
+ rbuf += sizeof(tp);
+ *rbuflen += 2;
+ }
+ else {
+ *rbuf++ = len;
+ *rbuflen++;
+ }
if ( len > 0 ) {
memcpy( rbuf, name, len );
}
- *rbuflen = len + 1;
+ *rbuflen += len;
return( AFP_OK );
}
{
struct passwd *pw;
struct group *gr;
- int len, sfunc;
- u_int32_t id;
+ int len, sfunc;
+ u_int32_t id;
+ u_int16_t ulen;
ibuf++;
sfunc = (unsigned char) *ibuf++;
- len = (unsigned char) *ibuf++;
+ switch ( sfunc ) {
+ case 1 :
+ case 2 : /* unicode */
+ memcpy(&ulen, ibuf, sizeof(ulen));
+ len = ntohs(ulen);
+ ibuf += 2;
+ break;
+ case 3 :
+ case 4 :
+ len = (unsigned char) *ibuf++;
+ break;
+ default :
+ *rbuflen = 0;
+ return( AFPERR_PARAM );
+ }
+
ibuf[ len ] = '\0';
if ( len != 0 ) {
switch ( sfunc ) {
+ case 1 : /* unicode */
case 3 :
if (( pw = (struct passwd *)getpwnam( ibuf )) == NULL ) {
*rbuflen = 0;
id = pw->pw_uid;
break;
+ case 2 : /* unicode */
case 4 :
if (( gr = (struct group *)getgrnam( ibuf )) == NULL ) {
*rbuflen = 0;
}
id = gr->gr_gid;
break;
- default :
- *rbuflen = 0;
- return( AFPERR_PARAM );
}
} else {
id = 0;
/*
- * $Id: file.c,v 1.63 2002-10-11 14:18:29 didg Exp $
+ * $Id: file.c,v 1.64 2002-10-12 04:02:46 didg Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
return data;
}
+/*
+ * FIXME: PDINFO is UTF8 and doesn't need adp
+*/
#define PARAM_NEED_ADP(b) ((b) & ((1 << FILPBIT_ATTR) |\
(1 << FILPBIT_CDATE) |\
(1 << FILPBIT_MDATE) |\
(1 << FILPBIT_PDINFO)))
+char *set_name(char *data, const char *name, u_int32_t utf8)
+{
+ u_int32_t aint;
+
+ aint = strlen( name );
+
+ if (!utf8) {
+ if (aint > MACFILELEN)
+ aint = MACFILELEN;
+ *data++ = aint;
+ }
+ else {
+ u_int16_t temp;
+
+ if (aint > 255) /* FIXME safeguard, anyway if no ascii char it's game over*/
+ aint = 255;
+
+ utf8 = htonl(utf8);
+ memcpy(data, &utf8, sizeof(utf8));
+ data += sizeof(utf8);
+
+ temp = htons(aint);
+ memcpy(data, &temp, sizeof(temp));
+ data += sizeof(temp);
+ }
+
+ memcpy( data, name, aint );
+ data += aint;
+
+ return data;
+}
+
+/* -------------------------- */
int getmetadata(struct vol *vol,
u_int16_t bitmap,
char *path, struct dir *dir, struct stat *st,
u_int32_t aint;
u_int16_t ashort;
u_char achar, fdType[4];
+ u_int32_t utf8 = 0;
#ifdef DEBUG
LOG(log_info, logtype_afpd, "begin getmetadata:");
to "pXYZ" when we created it. See IA, Ver 2.
<shirsch@ibm.net> */
case FILPBIT_PDINFO :
- if ( adp ) {
- memcpy(fdType, ad_entry( adp, ADEID_FINDERI ), 4 );
+ if (afp_version >= 30) { /* UTF8 name */
+ utf8 = kTextEncodingUTF8;
+ data += sizeof( u_int16_t );
+ }
+ else {
+ if ( adp ) {
+ memcpy(fdType, ad_entry( adp, ADEID_FINDERI ), 4 );
- if ( memcmp( fdType, "TEXT", 4 ) == 0 ) {
- achar = '\x04';
- ashort = 0x0000;
- }
- else if ( memcmp( fdType, "PSYS", 4 ) == 0 ) {
- achar = '\xff';
- ashort = 0x0000;
- }
- else if ( memcmp( fdType, "PS16", 4 ) == 0 ) {
- achar = '\xb3';
- ashort = 0x0000;
- }
- else if ( memcmp( fdType, "BINA", 4 ) == 0 ) {
- achar = '\x00';
- ashort = 0x0000;
- }
- else if ( fdType[0] == 'p' ) {
- achar = fdType[1];
- ashort = (fdType[2] * 256) + fdType[3];
+ if ( memcmp( fdType, "TEXT", 4 ) == 0 ) {
+ achar = '\x04';
+ ashort = 0x0000;
+ }
+ else if ( memcmp( fdType, "PSYS", 4 ) == 0 ) {
+ achar = '\xff';
+ ashort = 0x0000;
+ }
+ else if ( memcmp( fdType, "PS16", 4 ) == 0 ) {
+ achar = '\xb3';
+ ashort = 0x0000;
+ }
+ else if ( memcmp( fdType, "BINA", 4 ) == 0 ) {
+ achar = '\x00';
+ ashort = 0x0000;
+ }
+ else if ( fdType[0] == 'p' ) {
+ achar = fdType[1];
+ ashort = (fdType[2] * 256) + fdType[3];
+ }
+ else {
+ achar = '\x00';
+ ashort = 0x0000;
+ }
}
else {
achar = '\x00';
ashort = 0x0000;
}
- }
- else {
- achar = '\x00';
- ashort = 0x0000;
- }
- *data++ = achar;
- *data++ = 0;
- memcpy(data, &ashort, sizeof( ashort ));
- data += sizeof( ashort );
- memset(data, 0, sizeof( ashort ));
- data += sizeof( ashort );
+ *data++ = achar;
+ *data++ = 0;
+ memcpy(data, &ashort, sizeof( ashort ));
+ data += sizeof( ashort );
+ memset(data, 0, sizeof( ashort ));
+ data += sizeof( ashort );
+ }
break;
case FILPBIT_EXTDFLEN:
aint = htonl(st->st_size >> 32);
if ( nameoff ) {
ashort = htons( data - buf );
memcpy(nameoff, &ashort, sizeof( ashort ));
- if ((aint = strlen( path )) > MACFILELEN)
- aint = MACFILELEN;
- *data++ = aint;
- memcpy(data, path, aint );
- data += aint;
+ data = set_name(data, path, utf8);
}
*buflen = data - buf;
return (AFP_OK);
/*
- * $Id: file.h,v 1.12 2002-10-11 14:18:31 didg Exp $
+ * $Id: file.h,v 1.13 2002-10-12 04:02:46 didg Exp $
*
* Copyright (c) 1990,1991 Regents of The University of Michigan.
* All Rights Reserved.
char em_type[ 4 ];
};
+#define kTextEncodingUTF8 0x08000103
+extern char *set_name __P((char *, const char *, u_int32_t ) );
+
extern struct extmap *getextmap __P((const char *));
extern struct extmap *getdefextmap __P((void));
/*
- * $Id: switch.c,v 1.8 2002-08-25 13:26:20 rlewczuk Exp $
+ * $Id: switch.c,v 1.9 2002-10-12 04:02:46 didg Exp $
*
* Copyright (c) 1990,1991 Regents of The University of Michigan.
* All Rights Reserved.
NULL, NULL, NULL, NULL, /* 48 - 55 */
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, /* 56 - 63 */
- NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, afp_login_ext,
NULL, NULL, NULL, NULL, /* 64 - 71 */
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, /* 72 - 79 */
/*
- * $Id: volume.c,v 1.38 2002-10-11 14:18:35 didg Exp $
+ * $Id: volume.c,v 1.39 2002-10-12 04:02:46 didg Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
* it's passed in that way as it's possible to mount
* a read-write filesystem under a read-only one. */
if ((vol->v_flags & AFPVOL_RO) ||
- ((utime(vol->v_path, NULL) < 0) && (errno == EROFS)))
+ ((utime(vol->v_path, NULL) < 0) && (errno == EROFS))) {
ashort |= VOLPBIT_ATTR_RO;
+ }
#ifdef WITH_CATSEARCH
- ashort |= VOLPBIT_ATTR_CATSEARCH;
+ ashort |= VOLPBIT_ATTR_CATSEARCH;
#endif
+ if (afp_version >= 30) {
+ ashort |= VOLPBIT_ATTR_UTF8;
+ }
ashort = htons(ashort);
memcpy(data, &ashort, sizeof( ashort ));
data += sizeof( ashort );
#define AFP_ENUMERATE_EXT 66
#define AFP_READ_EXT 60
#define AFP_WRITE_EXT 61
+#define AFP_LOGIN_EXT 63
#define AFP_GETSESSTOKEN 64
#define AFP_DISCTOLDSESS 65