static int initprivate_x11display(/*out*/x11display_t * x11disp, const char * display_server_name, bool isInitExtension) { int err ; x11display_t newdisp = x11display_FREE; memblock_t mblock; if (!display_server_name) { display_server_name = getenv("DISPLAY") ; if (!display_server_name) { err = EINVAL; TRACE_NOARG_ERRLOG(log_flags_NONE, X11_DISPLAY_NOT_SET); goto ONERR; } } // create new x11_display err = ALLOC_MM(sizeof(x11windowmap_t), &mblock); if (err) goto ONERR; newdisp.idmap = (x11windowmap_t*) mblock.addr; memset(newdisp.idmap->entries, 0, sizeof(newdisp.idmap->entries)); newdisp.sys_display = XOpenDisplay(display_server_name); if (!newdisp.sys_display) { err = ECONNREFUSED; TRACE_ERRLOG(log_flags_NONE, X11_NO_CONNECTION, display_server_name); goto ONERR; } #define SETATOM(NAME) newdisp.atoms.NAME = XInternAtom(newdisp.sys_display, #NAME, False); \ static_assert(sizeof(newdisp.atoms.NAME) == sizeof(uint32_t), "same type") SETATOM(WM_PROTOCOLS); SETATOM(WM_DELETE_WINDOW); SETATOM(_NET_FRAME_EXTENTS); SETATOM(_NET_WM_WINDOW_OPACITY); #undef SETATOM if (isInitExtension) { err = queryextensions_x11display(&newdisp); if (err) goto ONERR; } *x11disp = newdisp; return 0; ONERR: free_x11display(&newdisp); TRACEEXIT_ERRLOG(err); return err; }
int new_syslogininfo(/*out*/syslogin_info_t** info, sys_userid_t uid) { int err; memblock_t mblock = memblock_FREE; slock_mutex(&s_syslogininfo_lock); errno = 0; struct passwd* pwd = getpwuid(uid); if (!pwd) { if (errno) { err = errno; TRACESYSCALL_ERRLOG("getpwuid(uid)", err); PRINTUINT32_ERRLOG(uid); } else { err = ENOENT; } goto UNLOCK; } size_t namesize = strlen(pwd->pw_name) + 1; // size username size_t nrofgrp = 0; #define GELEMSIZE (sizeof(sys_groupid_t) + sizeof(char*)) setgrent(); for (;;) { errno = 0; struct group* grp = getgrent(); if (!grp) { if (errno) { err = errno; TRACESYSCALL_ERRLOG("getgrent", err); goto UNLOCK; } break; } bool ismatch = (grp->gr_gid == pwd->pw_gid); for (int i = 0; !ismatch && grp->gr_mem[i]; ++i) { ismatch = (0 == strcmp(grp->gr_mem[i], pwd->pw_name)); } if (ismatch) { size_t len = strlen(grp->gr_name); if (nrofgrp == (SIZE_MAX/GELEMSIZE) || namesize >= SIZE_MAX/2 || len >= SIZE_MAX/2) { err = ENOMEM; goto UNLOCK; } nrofgrp ++; namesize += len + 1; } } size_t size = sizeof(syslogin_info_t) + namesize; size_t arrsize = nrofgrp * GELEMSIZE; if (size <= namesize) size = 0; size += arrsize; if (size <= arrsize) { err = ENOMEM; goto UNLOCK; } err = ALLOC_MM(size, &mblock); if (err) goto UNLOCK; syslogin_info_t* newobj = (syslogin_info_t*) mblock.addr; uint8_t* data = mblock.addr + sizeof(syslogin_info_t); size_t datasize = size - sizeof(syslogin_info_t); size_t dataoff; newobj->size = size; newobj->uid = uid; newobj->nrgroups = nrofgrp; newobj->gmain = 0; newobj->gname = (const char**) data; dataoff = nrofgrp * sizeof(char*); newobj->gid = (sys_groupid_t*) (data + dataoff); dataoff += nrofgrp * sizeof(sys_groupid_t); size_t fieldsize = strlen(pwd->pw_name) + 1; if (fieldsize > (datasize - dataoff)) { err = EAGAIN; goto UNLOCK; } memcpy(data + dataoff, pwd->pw_name, fieldsize); newobj->uname = (char*) (data + dataoff); dataoff += fieldsize; setgrent(); for (size_t gi = 0; gi < nrofgrp; ) { errno = 0; struct group* grp = getgrent(); if (!grp) { err = errno ? errno : ENOENT; TRACESYSCALL_ERRLOG("getgrent", err); goto UNLOCK; } bool ismatch = (grp->gr_gid == pwd->pw_gid); for (int i = 0; !ismatch && grp->gr_mem[i]; ++i) { ismatch = (0 == strcmp(grp->gr_mem[i], pwd->pw_name)); } if (ismatch) { fieldsize = strlen(grp->gr_name) + 1; if (fieldsize > (datasize - dataoff)) { err = EAGAIN; goto UNLOCK; } char* gname = (char*) (data + dataoff); dataoff += fieldsize; memcpy(gname, grp->gr_name, fieldsize); if (grp->gr_gid == pwd->pw_gid) { newobj->gmain = gi; } newobj->gid[gi] = grp->gr_gid; newobj->gname[gi] = gname; ++gi; } } *info = newobj; UNLOCK: endgrent(); endpwent(); sunlock_mutex(&s_syslogininfo_lock); if (err) goto ONERR; return 0; ONERR: FREE_MM(&mblock); if (ENOENT != err) { TRACEEXIT_ERRLOG(err); } return err; }