/* * map.c * * Copyright (C) 2007 Alex deVries * */ #include #include #include "afpfs-ng/dsi.h" #include "afpfs-ng/afp.h" #include "afpfs-ng/utils.h" #include "dsi_protocol.h" #include "afpfs-ng/afp_protocol.h" /* This is used to pass the return values back from afp_getuserinfo_reply() */ struct uidgid { unsigned int uid; unsigned int gid; }; int afp_getuserinfo(struct afp_server * server, int thisuser, unsigned int userid, unsigned short bitmap, unsigned int *newuid, unsigned int *newgid) { struct { struct dsi_header dsi_header __attribute__((__packed__)); uint8_t command; uint8_t thisuser; uint32_t userid __attribute__((__packed__)); uint16_t bitmap __attribute__((__packed__)); } __attribute__((__packed__)) request; struct uidgid uidgid; int ret; dsi_setup_header(server,&request.dsi_header,DSI_DSICommand); request.command=afpGetUserInfo; request.thisuser=(thisuser!=0); request.userid=htonl(userid); request.bitmap=htons(bitmap); ret=dsi_send(server, (char *) &request,sizeof(request), DSI_DEFAULT_TIMEOUT,afpGetUserInfo, (void *) &uidgid); if (bitmap & kFPGetUserInfo_USER_ID) *newuid=uidgid.uid; if (bitmap & kFPGetUserInfo_PRI_GROUPID) *newgid=uidgid.gid; return ret; } int afp_getuserinfo_reply(struct afp_server *server, char * buf, unsigned int size, void *other) { struct { struct dsi_header header __attribute__((__packed__)); uint16_t bitmap; uint32_t id1; uint32_t id2; } __attribute__((__packed__)) * reply= (void *) buf; struct uidgid *uidgid = other; unsigned short bitmap; uidgid->uid=0; uidgid->gid=0; if (size < sizeof (struct dsi_header)) return -1; bitmap=ntohs(reply->bitmap); if (reply->header.return_code.error_code!=kFPNoErr) return -1; if (bitmap & kFPGetUserInfo_USER_ID) { uidgid->uid=ntohl(reply->id1); if (bitmap & kFPGetUserInfo_PRI_GROUPID) uidgid->gid=ntohl(reply->id2); goto out; } if (bitmap & kFPGetUserInfo_PRI_GROUPID) { uidgid->gid=ntohl(reply->id1); } out: return 0; } int afp_mapid(struct afp_server * server, unsigned char subfunction, unsigned int id, char *name) { struct { struct dsi_header dsi_header __attribute__((__packed__)); uint8_t command; uint8_t subfunction; uint32_t id; } __attribute__((__packed__)) request; int ret; dsi_setup_header(server,&request.dsi_header,DSI_DSICommand); request.command=afpMapID; request.subfunction=subfunction; request.id=htonl(id); ret=dsi_send(server, (char *) &request,sizeof(request), DSI_DEFAULT_TIMEOUT,afpMapID,(void *) name); return ret; } int afp_mapid_reply(struct afp_server *server, char * buf, unsigned int size, void *other) { struct { struct dsi_header header __attribute__((__packed__)); char * name ; } __attribute__((__packed__)) * reply= (void *) buf; char * name = other; if (size < sizeof (struct dsi_header)) return -1; if (reply->header.return_code.error_code!=kFPNoErr) return -1; copy_from_pascal_two(name, &reply->name, 255); return 0; } int afp_mapname(struct afp_server * server, unsigned char subfunction, char * name, unsigned int * id) { struct { struct dsi_header dsi_header __attribute__((__packed__)); uint8_t command; uint8_t subfunction; } __attribute__((__packed__)) * request; unsigned int len=sizeof(*request)+ 1 + strlen(name); char * msg, * nameptr; int ret; if ((msg=malloc(len)) == NULL) return -1; memset(msg,0x4b,len); nameptr=msg+sizeof(*request); request = (void *) msg; copy_to_pascal(nameptr,name); dsi_setup_header(server,&request->dsi_header,DSI_DSICommand); request->command=afpMapName; request->subfunction=subfunction; ret=dsi_send(server, (char *) request,len, DSI_DEFAULT_TIMEOUT,afpMapName,(void *) id); free(msg); return ret; } int afp_mapname_reply(struct afp_server *server, char * buf, unsigned int size, void *other) { struct { struct dsi_header header __attribute__((__packed__)); uint32_t id ; } __attribute__((__packed__))* reply= (void *) buf; unsigned int * id = (void *) other; if (size < sizeof (struct dsi_header)) return -1; *id=ntohl(reply->id); return 0; }