/* WARNING: This file was generated by dkct. 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 */ /* Copyright (C) 2015-2017, Dirk Krause Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above opyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the author nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @file dk4user.c The dk4user module. */ #line 87 "dk4user.ctr" #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" #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 #line 140 "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 160 "dk4user.ctr" }; #endif int dk4user_get_logname(dkChar *pdst, size_t szdst, int eff, dk4_er_t *erp) { #if DK4_ON_WINDOWS DWORD sz; int back = 0; #line 170 "dk4user.ctr" 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 192 "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 202 "dk4user.ctr" 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 219 "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 256 "dk4user.ctr" dk4error_init(&er); if (GetUserNameW(logname, &szlog)) { #line 258 "dk4user.ctr" if (DK4_SIZEOF(logname,wchar_t) >= szlog) { #line 259 "dk4user.ctr" logname[szlog] = L'\0'; nStatus = NetUserGetInfo(lsn, logname, (DWORD)4, (LPBYTE *)(&pbuf4)); if ((NERR_Success == nStatus) && (NULL != pbuf4)) { #line 262 "dk4user.ctr" if (ConvertSidToStringSidW(pbuf4->usri4_user_sid, &pStringSid)) { #line 264 "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 278 "dk4user.ctr" (void)dk4ma_size_t_mul(sizeof(wchar_t), sz, &er); if (DK4_E_NONE == er.ec) { #line 280 "dk4user.ctr" keyname = dk4mem_calloc(sizeof(wchar_t),sz,&er); if (NULL != keyname) { #line 282 "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 287 "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 295 "dk4user.ctr" dk4wreg_close_key(wrkey); } else { #line 297 "dk4user.ctr" /* ERROR: Failed to open key (reported) */ } dk4mem_free(keyname); } else { #line 301 "dk4user.ctr" /* ERROR: Memory (reported) */ } } else { #line 304 "dk4user.ctr" /* ERROR: Overflow in size calculation (reported) */ } } else { #line 307 "dk4user.ctr" /* ERROR: Overflow in size calculation (reported) */ } } else { #line 310 "dk4user.ctr" /* ERROR: Failed to convert SID */ dk4error_set_simple_error_code(&er, DK4_E_NOT_FOUND); } if (NULL != pStringSid) { LocalFree(pStringSid); } } else { #line 317 "dk4user.ctr" /* ERROR: No user info */ } if (NULL != pbuf4) { NetApiBufferFree(pbuf4); } } else { #line 323 "dk4user.ctr" /* ERROR: User name too long */ dk4error_set_simple_error_code(&er, DK4_E_BUFFER_TOO_SMALL); } } else { #line 327 "dk4user.ctr" /* ERROR: User name not found */ } if (0 == back) { dk4error_copy(erp, &er); } #line 333 "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 353 "dk4user.ctr" dk4error_init(&myerp); back = dk4user_get_i_ls_homedir(pdst, szdst, NULL, &myerp); #line 356 "dk4user.ctr" if ((0 == back) && (DK4_E_NONE == myerp.ec)) { #line 357 "dk4user.ctr" lsn = _wgetenv(dk4user_kw[4]); #line 358 "dk4user.ctr" if (NULL != lsn) { back = dk4strw_cpy_s(pdst, szdst, lsn, &myerp); #line 361 "dk4user.ctr" } else { #line 362 "dk4user.ctr" } } if ((0 == back) && (DK4_E_NONE == myerp.ec)) { #line 365 "dk4user.ctr" lsn = _wgetenv(dk4user_kw[5]); hop = _wgetenv(dk4user_kw[6]); if ((NULL != lsn) && (NULL != hop)) { #line 368 "dk4user.ctr" if (0 != dk4strw_cpy_s(pdst, szdst, lsn, &myerp)) { back = dk4strw_cat_s(pdst, szdst, hop, &myerp); #line 371 "dk4user.ctr" } else { #line 372 "dk4user.ctr" } } else { #line 374 "dk4user.ctr" } } if ((0 == back) && (DK4_E_NONE == myerp.ec)) { #line 377 "dk4user.ctr" lsn = _wgetenv(dk4user_kw[3]); if (NULL != lsn) { #line 379 "dk4user.ctr" back = dk4user_get_i_ls_homedir(pdst, szdst, lsn, &myerp); #line 381 "dk4user.ctr" } } if ((0 == back) && (DK4_E_NONE == myerp.ec)) { #line 384 "dk4user.ctr" if (NULL != lsn) { #line 385 "dk4user.ctr" if (L'\\' == lsn[0]) { if (L'\\' == lsn[1]) { back = dk4user_get_i_ls_homedir(pdst, szdst, &(lsn[2]), &myerp); #line 389 "dk4user.ctr" } else { #line 390 "dk4user.ctr" } } else { #line 392 "dk4user.ctr" } } else { #line 394 "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 402 "dk4user.ctr" return back; } #endif int dk4user_get_homedir(dkChar *pdst, size_t szdst, int eff, 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 418 "dk4user.ctr" if ((NULL != pdst) && (0 < szdst)) { #line 419 "dk4user.ctr" *pdst = dkT('\0'); #if DK4_CHAR_SIZE > 1 #line 422 "dk4user.ctr" back = dk4user_get_i_homedir(pdst, szdst, erp); #else #line 425 "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 432 "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 447 "dk4user.ctr" 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 464 "dk4user.ctr" return back; /* ----- non-Windows char ----- */ #endif /* ----- non-Windows ----- */ #endif }