/* Copyright (C) 2015-2020, Dirk Krause SPDX-License-Identifier: BSD-3-Clause */ /* WARNING: This file was generated by the dkct program (see http://dktools.sourceforge.net/ for details). Changes you make here will be lost if dkct is run again! You should modify the original source and run dkct on it. Original source: dk4user.ctr */ /** @file dk4user.c The dk4user module. */ #line 99 "dk4user.ctr" #include "dk4conf.h" #include "dk4user.h" #include "dk4str8.h" #include "dk4strw.h" #include "dk4strd.h" #include "dk4wregw.h" #include "dk4wregc.h" #include "dk4mem.h" #include "dk4error.h" #include "dk4masz.h" #include "dk4mpl.h" #include "dk4unused.h" #if DK4_ON_WINDOWS #ifndef WINDOWS_H_INCLUDED #include #define WINDOWS_H_INCLUDED 1 #endif #ifndef LM_H_INCLUDED #include #define LM_H_INCLUDED 1 #endif #ifndef SDDL_H_INCLUDED #include #define SDDL_H_INCLUDED 1 #endif #endif #if DK4_HAVE_SYS_TYPES_H #ifndef SYS_TYPES_H_INCLUDED #include #define SYS_TYPES_H_INCLUDED 1 #endif #endif #if DK4_HAVE_UNISTD_H #ifndef UNISTD_H_INCLUDED #include #define UNISTD_H_INCLUDED 1 #endif #endif #if DK4_HAVE_PWD_H #ifndef PWD_H_INCLUDED #include #define PWD_H_INCLUDED 1 #endif #endif #if DK4_HAVE_ASSERT_H #ifndef ASSERT_H_INCLUDED #include #define ASSERT_H_INCLUDED 1 #endif #endif #line 160 "dk4user.ctr" #if DK4_ON_WINDOWS static const wchar_t * const dk4user_kw[] = { /* 0 */ L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList", /* 1 */ L"\\", /* 2 */ L"ProfileImagePath", /* 3 */ L"LOGONSERVER", /* 4 */ L"USERPROFILE", /* 5 */ L"HOMEDRIVE", /* 6 */ L"HOMEPATH", NULL #line 180 "dk4user.ctr" }; #endif int dk4user_get_logname( dkChar *pdst, size_t szdst, #if DK4_ON_WINDOWS int DK4_ARG_UNUSED(eff), #else int eff, #endif dk4_er_t *erp ) { #if DK4_ON_WINDOWS DWORD sz; int back = 0; #line 199 "dk4user.ctr" DK4_UNUSED_ARG(eff) #if DK4_USE_ASSERT assert(NULL != pdst); assert(0 < szdst); #endif if ((NULL != pdst) && (0 < szdst)) { sz = (DWORD)szdst; #if DK4_CHAR_SIZE > 1 if(GetUserNameW(pdst, &sz)) #else if(GetUserNameA(pdst, &sz)) #endif { if (sz < szdst) { pdst[sz] = dkT('\0'); back = 1; } else { dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL); } } else { dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND); } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } #line 226 "dk4user.ctr" return back; #else #if DK4_CHAR_SIZE > 1 dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED); return 0; #else struct passwd *pwent; uid_t uid; int back = 0; #line 236 "dk4user.ctr" #if DK4_USE_ASSERT assert(NULL != pdst); assert(0 < szdst); #endif if ((NULL != pdst) && (0 < szdst)) { if (0 != eff) { uid = geteuid(); } else { uid = getuid(); } pwent = getpwuid(uid); if (NULL != pwent) { if (NULL != pwent->pw_name) { if (0 != dk4str_cpy_s(pdst, szdst, pwent->pw_name, erp)) { back = 1; } } else { dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND); } } else { dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND); } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } #line 257 "dk4user.ctr" return back; #endif #endif } #if DK4_ON_WINDOWS /** Obtain home directory information using one logon server. @param pdst Destination buffer pointer. @param szdst Destination buffer size (number of wchar_t). @param lsn Logon server name, may be NULL. @param erp Error report, may be NULL. @return 1 on success, 0 on error. */ static int dk4user_get_i_ls_homedir( wchar_t *pdst, size_t szdst, const wchar_t *lsn, dk4_er_t *erp ) { wchar_t b1[DK4_MAX_PATH+16]; /* Buffer RegQueryValue() */ wchar_t b2[DK4_MAX_PATH+16]; /* Buffer Expand...() */ wchar_t logname[256]; /* Login name */ dk4_er_t er; /* Error report */ USER_INFO_4 *pbuf4 = NULL; /* User information */ wchar_t *pStringSid = NULL; /* String SID */ wchar_t *keyname = NULL; /* Registry key name */ void *wrkey = NULL; /* Registry key */ DWORD szlog = DK4_SIZEOF(logname,wchar_t); size_t sz = 0; /* Key name length */ int back = 0; /* Result */ NET_API_STATUS nStatus = 0; /* Network op result */ #line 294 "dk4user.ctr" #if DK4_USE_ASSERT assert(NULL != pdst); assert(0 < szdst); #endif dk4error_init(&er); if (GetUserNameW(logname, &szlog)) { #line 300 "dk4user.ctr" if (DK4_SIZEOF(logname,wchar_t) >= szlog) { #line 301 "dk4user.ctr" logname[szlog] = L'\0'; nStatus = NetUserGetInfo(lsn, logname, (DWORD)4, (LPBYTE *)(&pbuf4)); if ((NERR_Success == nStatus) && (NULL != pbuf4)) { #line 304 "dk4user.ctr" if (ConvertSidToStringSidW(pbuf4->usri4_user_sid, &pStringSid)) { #line 306 "dk4user.ctr" sz = dk4ma_size_t_add( dk4ma_size_t_add( 1, dk4strw_len(dk4user_kw[0]), &er ), dk4ma_size_t_add( dk4strw_len(dk4user_kw[1]), dk4strw_len(pStringSid), &er ), &er ); if (DK4_E_NONE == er.ec) { #line 320 "dk4user.ctr" (void)dk4ma_size_t_mul(sizeof(wchar_t), sz, &er); if (DK4_E_NONE == er.ec) { #line 322 "dk4user.ctr" keyname = dk4mem_calloc(sizeof(wchar_t),sz,&er); if (NULL != keyname) { #line 324 "dk4user.ctr" (void)dk4strw_cpy_s(keyname, sz, dk4user_kw[0], NULL); (void)dk4strw_cat_s(keyname, sz, dk4user_kw[1], NULL); (void)dk4strw_cat_s(keyname, sz, pStringSid, NULL); wrkey = dk4wreg_open_key_wc(DK4_WREGKEY_HKLM, keyname, 0, &er); if (NULL != wrkey) { #line 329 "dk4user.ctr" back = dk4wreg_get_expanded_string_wc( wrkey, dk4user_kw[2], pdst, szdst, b1, DK4_SIZEOF(b1,wchar_t), b2, (DK4_SIZEOF(b2,wchar_t)-2), &er ); #line 337 "dk4user.ctr" dk4wreg_close_key(wrkey); } else { #line 339 "dk4user.ctr" /* ERROR: Failed to open key (reported) */ } dk4mem_free(keyname); } else { #line 343 "dk4user.ctr" /* ERROR: Memory (reported) */ } } else { #line 346 "dk4user.ctr" /* ERROR: Overflow in size calculation (reported) */ } } else { #line 349 "dk4user.ctr" /* ERROR: Overflow in size calculation (reported) */ } } else { #line 352 "dk4user.ctr" /* ERROR: Failed to convert SID */ dk4error_set_simple_error_code(&er, DK4_E_NOT_FOUND); } if (NULL != pStringSid) { LocalFree(pStringSid); } } else { #line 359 "dk4user.ctr" /* ERROR: No user info */ } if (NULL != pbuf4) { NetApiBufferFree(pbuf4); } } else { #line 365 "dk4user.ctr" /* ERROR: User name too long */ dk4error_set_simple_error_code(&er, DK4_E_BUFFER_TOO_SMALL); } } else { #line 369 "dk4user.ctr" /* ERROR: User name not found */ } if (0 == back) { dk4error_copy(erp, &er); } #line 375 "dk4user.ctr" return back; } /** Find Windows home directory. @param pdst Destination buffer pointer. @param szdst Destination buffer size (number of wchar_t). @param erp Error report, may be NULL. @return 1 on success, 0 on error. */ static int dk4user_get_i_homedir(wchar_t *pdst, size_t szdst, dk4_er_t *erp) { dk4_er_t myerp; wchar_t *lsn = NULL; wchar_t *hop = NULL; int back = 0; #line 395 "dk4user.ctr" #if DK4_USE_ASSERT assert(NULL != pdst); assert(0 < szdst); #endif dk4error_init(&myerp); back = dk4user_get_i_ls_homedir(pdst, szdst, NULL, &myerp); #line 402 "dk4user.ctr" if ((0 == back) && (DK4_E_NONE == myerp.ec)) { #line 403 "dk4user.ctr" lsn = _wgetenv(dk4user_kw[4]); #line 404 "dk4user.ctr" if (NULL != lsn) { back = dk4strw_cpy_s(pdst, szdst, lsn, &myerp); #line 407 "dk4user.ctr" } else { #line 408 "dk4user.ctr" } } if ((0 == back) && (DK4_E_NONE == myerp.ec)) { #line 411 "dk4user.ctr" lsn = _wgetenv(dk4user_kw[5]); hop = _wgetenv(dk4user_kw[6]); if ((NULL != lsn) && (NULL != hop)) { #line 414 "dk4user.ctr" if (0 != dk4strw_cpy_s(pdst, szdst, lsn, &myerp)) { back = dk4strw_cat_s(pdst, szdst, hop, &myerp); #line 417 "dk4user.ctr" } else { #line 418 "dk4user.ctr" } } else { #line 420 "dk4user.ctr" } } if ((0 == back) && (DK4_E_NONE == myerp.ec)) { #line 423 "dk4user.ctr" lsn = _wgetenv(dk4user_kw[3]); if (NULL != lsn) { #line 425 "dk4user.ctr" back = dk4user_get_i_ls_homedir(pdst, szdst, lsn, &myerp); #line 427 "dk4user.ctr" } } if ((0 == back) && (DK4_E_NONE == myerp.ec)) { #line 430 "dk4user.ctr" if (NULL != lsn) { #line 431 "dk4user.ctr" if (L'\\' == lsn[0]) { if (L'\\' == lsn[1]) { back = dk4user_get_i_ls_homedir(pdst, szdst, &(lsn[2]), &myerp); #line 435 "dk4user.ctr" } else { #line 436 "dk4user.ctr" } } else { #line 438 "dk4user.ctr" } } else { #line 440 "dk4user.ctr" } } if ((0 == back) && (DK4_E_NONE == myerp.ec)) { dk4error_set_simple_error_code(&myerp, DK4_E_NOT_FOUND); } if (0 == back) { dk4error_copy(erp, &myerp); } #line 448 "dk4user.ctr" return back; } #endif int dk4user_get_homedir( dkChar *pdst, size_t szdst, #if DK4_ON_WINDOWS int DK4_ARG_UNUSED(eff), #else int eff, #endif dk4_er_t *erp ) { #if DK4_ON_WINDOWS /* +++++ Windows +++++ */ #if DK4_CHAR_SIZE == 1 wchar_t homew[DK4_MAX_PATH]; #endif int back = 0; #line 473 "dk4user.ctr" DK4_UNUSED_ARG(eff) #if DK4_USE_ASSERT assert(NULL != pdst); assert(0 < szdst); #endif if ((NULL != pdst) && (0 < szdst)) { #line 479 "dk4user.ctr" *pdst = dkT('\0'); #if DK4_CHAR_SIZE > 1 #line 482 "dk4user.ctr" back = dk4user_get_i_homedir(pdst, szdst, erp); #else #line 485 "dk4user.ctr" if (0 != dk4user_get_i_homedir(homew, DK4_SIZEOF(homew,wchar_t), erp)) { back = dk4recode_utf16_to_ansi(pdst, szdst, homew, erp); } #endif } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } #line 492 "dk4user.ctr" return back; /* ----- Windows ----- */ #else /* +++++ non-Windows +++++ */ #if DK4_CHAR_SIZE > 1 /* +++++ non-Windows wchar_t +++++ */ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED); return 0; /* ----- non-Windows wchar_t ----- */ #else /* +++++ non-Windows char +++++ */ struct passwd *pwent; uid_t uid; int back = 0; #line 507 "dk4user.ctr" #if DK4_USE_ASSERT assert(NULL != pdst); assert(0 < szdst); #endif if ((NULL != pdst) && (0 < szdst)) { if (0 != eff) { uid = geteuid(); } else { uid = getuid(); } pwent = getpwuid(uid); if (NULL != pwent) { if (NULL != pwent->pw_dir) { if (0 != dk4str8_cpy_s(pdst, szdst, pwent->pw_dir, erp)) { back = 1; } } else { dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND); } } else { dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND); } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } #line 528 "dk4user.ctr" return back; /* ----- non-Windows char ----- */ #endif /* ----- non-Windows ----- */ #endif }