ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

access.c
Go to the documentation of this file.
00001 /*
00002  * Copyright 2002 Andriy Palamarchuk
00003  *
00004  * netapi32 access functions
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00019  */
00020 
00021 #include <stdarg.h>
00022 
00023 #include "ntstatus.h"
00024 #define WIN32_NO_STATUS
00025 #include "windef.h"
00026 #include "winbase.h"
00027 #include "winerror.h"
00028 #include "lmcons.h"
00029 #include "lmaccess.h"
00030 #include "lmapibuf.h"
00031 #include "lmerr.h"
00032 #include "lmuse.h"
00033 #include "ntsecapi.h"
00034 #include "wine/debug.h"
00035 #include "wine/unicode.h"
00036 #include "wine/list.h"
00037 
00038 WINE_DEFAULT_DEBUG_CHANNEL(netapi32);
00039 
00040 /* NOTE: So far, this is implemented to support tests that require user logins,
00041  *       but not designed to handle real user databases. Those should probably
00042  *       be synced with either the host's user database or with Samba.
00043  *
00044  * FIXME: The user database should hold all the information the USER_INFO_4 struct
00045  * needs, but for the first try, I will just implement the USER_INFO_1 fields.
00046  */
00047 
00048 struct sam_user
00049 {
00050     struct list entry;
00051     WCHAR user_name[LM20_UNLEN+1];
00052     WCHAR user_password[PWLEN + 1];
00053     DWORD sec_since_passwd_change;
00054     DWORD user_priv;
00055     LPWSTR home_dir;
00056     LPWSTR user_comment;
00057     DWORD user_flags;
00058     LPWSTR user_logon_script_path;
00059 };
00060 
00061 static struct list user_list = LIST_INIT( user_list );
00062 
00063 BOOL NETAPI_IsLocalComputer(LPCWSTR ServerName);
00064 
00065 /************************************************************
00066  *                NETAPI_ValidateServername
00067  *
00068  * Validates server name
00069  */
00070 static NET_API_STATUS NETAPI_ValidateServername(LPCWSTR ServerName)
00071 {
00072     if (ServerName)
00073     {
00074         if (ServerName[0] == 0)
00075             return ERROR_BAD_NETPATH;
00076         else if (
00077             ((ServerName[0] == '\\') &&
00078              (ServerName[1] != '\\'))
00079             ||
00080             ((ServerName[0] == '\\') &&
00081              (ServerName[1] == '\\') &&
00082              (ServerName[2] == 0))
00083             )
00084             return ERROR_INVALID_NAME;
00085     }
00086     return NERR_Success;
00087 }
00088 
00089 /************************************************************
00090  *                NETAPI_FindUser
00091  *
00092  * Looks for a user in the user database.
00093  * Returns a pointer to the entry in the user list when the user
00094  * is found, NULL otherwise.
00095  */
00096 static struct sam_user* NETAPI_FindUser(LPCWSTR UserName)
00097 {
00098     struct sam_user *user;
00099 
00100     LIST_FOR_EACH_ENTRY(user, &user_list, struct sam_user, entry)
00101     {
00102         if(lstrcmpW(user->user_name, UserName) == 0)
00103             return user;
00104     }
00105     return NULL;
00106 }
00107 
00108 static BOOL NETAPI_IsCurrentUser(LPCWSTR username)
00109 {
00110     LPWSTR curr_user = NULL;
00111     DWORD dwSize;
00112     BOOL ret = FALSE;
00113 
00114     dwSize = LM20_UNLEN+1;
00115     curr_user = HeapAlloc(GetProcessHeap(), 0, dwSize * sizeof(WCHAR));
00116     if(!curr_user)
00117     {
00118         ERR("Failed to allocate memory for user name.\n");
00119         goto end;
00120     }
00121     if(!GetUserNameW(curr_user, &dwSize))
00122     {
00123         ERR("Failed to get current user's user name.\n");
00124         goto end;
00125     }
00126     if (!lstrcmpW(curr_user, username))
00127     {
00128         ret = TRUE;
00129     }
00130 
00131 end:
00132     HeapFree(GetProcessHeap(), 0, curr_user);
00133     return ret;
00134 }
00135 
00136 /************************************************************
00137  *                NetUserAdd (NETAPI32.@)
00138  */
00139 NET_API_STATUS WINAPI NetUserAdd(LPCWSTR servername,
00140                   DWORD level, LPBYTE bufptr, LPDWORD parm_err)
00141 {
00142     NET_API_STATUS status;
00143     struct sam_user * su = NULL;
00144 
00145     FIXME("(%s, %d, %p, %p) stub!\n", debugstr_w(servername), level, bufptr, parm_err);
00146 
00147     if((status = NETAPI_ValidateServername(servername)) != NERR_Success)
00148         return status;
00149 
00150     switch(level)
00151     {
00152     /* Level 3 and 4 are identical for the purposes of NetUserAdd */
00153     case 4:
00154     case 3:
00155         FIXME("Level 3 and 4 not implemented.\n");
00156         /* Fall through */
00157     case 2:
00158         FIXME("Level 2 not implemented.\n");
00159         /* Fall through */
00160     case 1:
00161     {
00162         PUSER_INFO_1 ui = (PUSER_INFO_1) bufptr;
00163         su = HeapAlloc(GetProcessHeap(), 0, sizeof(struct sam_user));
00164         if(!su)
00165         {
00166             status = NERR_InternalError;
00167             break;
00168         }
00169 
00170         if(lstrlenW(ui->usri1_name) > LM20_UNLEN)
00171         {
00172             status = NERR_BadUsername;
00173             break;
00174         }
00175 
00176         /*FIXME: do other checks for a valid username */
00177         lstrcpyW(su->user_name, ui->usri1_name);
00178 
00179         if(lstrlenW(ui->usri1_password) > PWLEN)
00180         {
00181             /* Always return PasswordTooShort on invalid passwords. */
00182             status = NERR_PasswordTooShort;
00183             break;
00184         }
00185         lstrcpyW(su->user_password, ui->usri1_password);
00186 
00187         su->sec_since_passwd_change = ui->usri1_password_age;
00188         su->user_priv = ui->usri1_priv;
00189         su->user_flags = ui->usri1_flags;
00190 
00191         /*FIXME: set the other LPWSTRs to NULL for now */
00192         su->home_dir = NULL;
00193         su->user_comment = NULL;
00194         su->user_logon_script_path = NULL;
00195 
00196         list_add_head(&user_list, &su->entry);
00197         return NERR_Success;
00198     }
00199     default:
00200         TRACE("Invalid level %d specified.\n", level);
00201         status = ERROR_INVALID_LEVEL;
00202         break;
00203     }
00204 
00205     HeapFree(GetProcessHeap(), 0, su);
00206 
00207     return status;
00208 }
00209 
00210 /************************************************************
00211  *                NetUserDel  (NETAPI32.@)
00212  */
00213 NET_API_STATUS WINAPI NetUserDel(LPCWSTR servername, LPCWSTR username)
00214 {
00215     NET_API_STATUS status;
00216     struct sam_user *user;
00217 
00218     TRACE("(%s, %s)\n", debugstr_w(servername), debugstr_w(username));
00219 
00220     if((status = NETAPI_ValidateServername(servername))!= NERR_Success)
00221         return status;
00222 
00223     if ((user = NETAPI_FindUser(username)) == NULL)
00224         return NERR_UserNotFound;
00225 
00226     list_remove(&user->entry);
00227 
00228     HeapFree(GetProcessHeap(), 0, user->home_dir);
00229     HeapFree(GetProcessHeap(), 0, user->user_comment);
00230     HeapFree(GetProcessHeap(), 0, user->user_logon_script_path);
00231     HeapFree(GetProcessHeap(), 0, user);
00232 
00233     return NERR_Success;
00234 }
00235 
00236 /************************************************************
00237  *                NetUserGetInfo  (NETAPI32.@)
00238  */
00239 NET_API_STATUS WINAPI
00240 NetUserGetInfo(LPCWSTR servername, LPCWSTR username, DWORD level,
00241                LPBYTE* bufptr)
00242 {
00243     NET_API_STATUS status;
00244     TRACE("(%s, %s, %d, %p)\n", debugstr_w(servername), debugstr_w(username),
00245           level, bufptr);
00246     status = NETAPI_ValidateServername(servername);
00247     if (status != NERR_Success)
00248         return status;
00249 
00250     if(!NETAPI_IsLocalComputer(servername))
00251     {
00252         FIXME("Only implemented for local computer, but remote server"
00253               "%s was requested.\n", debugstr_w(servername));
00254         return NERR_InvalidComputer;
00255     }
00256 
00257     if(!NETAPI_FindUser(username) && !NETAPI_IsCurrentUser(username))
00258     {
00259         TRACE("User %s is unknown.\n", debugstr_w(username));
00260         return NERR_UserNotFound;
00261     }
00262 
00263     switch (level)
00264     {
00265     case 0:
00266     {
00267         PUSER_INFO_0 ui;
00268         int name_sz;
00269 
00270         name_sz = lstrlenW(username) + 1;
00271 
00272         /* set up buffer */
00273         NetApiBufferAllocate(sizeof(USER_INFO_0) + name_sz * sizeof(WCHAR),
00274                              (LPVOID *) bufptr);
00275 
00276         ui = (PUSER_INFO_0) *bufptr;
00277         ui->usri0_name = (LPWSTR) (*bufptr + sizeof(USER_INFO_0));
00278 
00279         /* get data */
00280         lstrcpyW(ui->usri0_name, username);
00281         break;
00282     }
00283 
00284     case 10:
00285     {
00286         PUSER_INFO_10 ui;
00287         PUSER_INFO_0 ui0;
00288         NET_API_STATUS status;
00289         /* sizes of the field buffers in WCHARS */
00290         int name_sz, comment_sz, usr_comment_sz, full_name_sz;
00291 
00292         comment_sz = 1;
00293         usr_comment_sz = 1;
00294         full_name_sz = 1;
00295 
00296         /* get data */
00297         status = NetUserGetInfo(servername, username, 0, (LPBYTE *) &ui0);
00298         if (status != NERR_Success)
00299         {
00300             NetApiBufferFree(ui0);
00301             return status;
00302         }
00303         name_sz = lstrlenW(ui0->usri0_name) + 1;
00304 
00305         /* set up buffer */
00306         NetApiBufferAllocate(sizeof(USER_INFO_10) +
00307                              (name_sz + comment_sz + usr_comment_sz +
00308                               full_name_sz) * sizeof(WCHAR),
00309                              (LPVOID *) bufptr);
00310         ui = (PUSER_INFO_10) *bufptr;
00311         ui->usri10_name = (LPWSTR) (*bufptr + sizeof(USER_INFO_10));
00312         ui->usri10_comment = (LPWSTR) (
00313             ((PBYTE) ui->usri10_name) + name_sz * sizeof(WCHAR));
00314         ui->usri10_usr_comment = (LPWSTR) (
00315             ((PBYTE) ui->usri10_comment) + comment_sz * sizeof(WCHAR));
00316         ui->usri10_full_name = (LPWSTR) (
00317             ((PBYTE) ui->usri10_usr_comment) + usr_comment_sz * sizeof(WCHAR));
00318 
00319         /* set data */
00320         lstrcpyW(ui->usri10_name, ui0->usri0_name);
00321         NetApiBufferFree(ui0);
00322         ui->usri10_comment[0] = 0;
00323         ui->usri10_usr_comment[0] = 0;
00324         ui->usri10_full_name[0] = 0;
00325         break;
00326     }
00327 
00328     case 1:
00329       {
00330         static const WCHAR homedirW[] = {'H','O','M','E',0};
00331         PUSER_INFO_1 ui;
00332         PUSER_INFO_0 ui0;
00333         NET_API_STATUS status;
00334         /* sizes of the field buffers in WCHARS */
00335         int name_sz, password_sz, home_dir_sz, comment_sz, script_path_sz;
00336 
00337         password_sz = 1; /* not filled out for security reasons for NetUserGetInfo*/
00338         comment_sz = 1;
00339         script_path_sz = 1;
00340 
00341        /* get data */
00342         status = NetUserGetInfo(servername, username, 0, (LPBYTE *) &ui0);
00343         if (status != NERR_Success)
00344         {
00345             NetApiBufferFree(ui0);
00346             return status;
00347         }
00348         name_sz = lstrlenW(ui0->usri0_name) + 1;
00349         home_dir_sz = GetEnvironmentVariableW(homedirW, NULL,0);
00350         /* set up buffer */
00351         NetApiBufferAllocate(sizeof(USER_INFO_1) +
00352                              (name_sz + password_sz + home_dir_sz +
00353                               comment_sz + script_path_sz) * sizeof(WCHAR),
00354                              (LPVOID *) bufptr);
00355 
00356         ui = (PUSER_INFO_1) *bufptr;
00357         ui->usri1_name = (LPWSTR) (ui + 1);
00358         ui->usri1_password = ui->usri1_name + name_sz;
00359         ui->usri1_home_dir = ui->usri1_password + password_sz;
00360         ui->usri1_comment = ui->usri1_home_dir + home_dir_sz;
00361         ui->usri1_script_path = ui->usri1_comment + comment_sz;
00362         /* set data */
00363         lstrcpyW(ui->usri1_name, ui0->usri0_name);
00364         NetApiBufferFree(ui0);
00365         ui->usri1_password[0] = 0;
00366         ui->usri1_password_age = 0;
00367         ui->usri1_priv = 0;
00368         GetEnvironmentVariableW(homedirW, ui->usri1_home_dir,home_dir_sz);
00369         ui->usri1_comment[0] = 0;
00370         ui->usri1_flags = 0;
00371         ui->usri1_script_path[0] = 0;
00372         break;
00373       }
00374     case 2:
00375     case 3:
00376     case 4:
00377     case 11:
00378     case 20:
00379     case 23:
00380     case 1003:
00381     case 1005:
00382     case 1006:
00383     case 1007:
00384     case 1008:
00385     case 1009:
00386     case 1010:
00387     case 1011:
00388     case 1012:
00389     case 1013:
00390     case 1014:
00391     case 1017:
00392     case 1018:
00393     case 1020:
00394     case 1023:
00395     case 1024:
00396     case 1025:
00397     case 1051:
00398     case 1052:
00399     case 1053:
00400     {
00401         FIXME("Level %d is not implemented\n", level);
00402         return NERR_InternalError;
00403     }
00404     default:
00405         TRACE("Invalid level %d is specified\n", level);
00406         return ERROR_INVALID_LEVEL;
00407     }
00408     return NERR_Success;
00409 }
00410 
00411 /************************************************************
00412  *                NetUserGetLocalGroups  (NETAPI32.@)
00413  */
00414 NET_API_STATUS WINAPI
00415 NetUserGetLocalGroups(LPCWSTR servername, LPCWSTR username, DWORD level,
00416                       DWORD flags, LPBYTE* bufptr, DWORD prefmaxlen,
00417                       LPDWORD entriesread, LPDWORD totalentries)
00418 {
00419     NET_API_STATUS status;
00420     const WCHAR admins[] = {'A','d','m','i','n','i','s','t','r','a','t','o','r','s',0};
00421     LPWSTR currentuser;
00422     LOCALGROUP_USERS_INFO_0* info;
00423     DWORD size;
00424 
00425     FIXME("(%s, %s, %d, %08x, %p %d, %p, %p) stub!\n",
00426           debugstr_w(servername), debugstr_w(username), level, flags, bufptr,
00427           prefmaxlen, entriesread, totalentries);
00428 
00429     status = NETAPI_ValidateServername(servername);
00430     if (status != NERR_Success)
00431         return status;
00432 
00433     size = UNLEN + 1;
00434     NetApiBufferAllocate(size * sizeof(WCHAR), (LPVOID*)&currentuser);
00435     GetUserNameW(currentuser, &size);
00436 
00437     if (lstrcmpiW(username, currentuser) && NETAPI_FindUser(username))
00438     {
00439         NetApiBufferFree(currentuser);
00440         return NERR_UserNotFound;
00441     }
00442 
00443     NetApiBufferFree(currentuser);
00444     *totalentries = 1;
00445     size = sizeof(*info) + sizeof(admins);
00446 
00447     if(prefmaxlen < size)
00448         status = ERROR_MORE_DATA;
00449     else
00450         status = NetApiBufferAllocate(size, (LPVOID*)&info);
00451 
00452     if(status != NERR_Success)
00453     {
00454         *bufptr = NULL;
00455         *entriesread = 0;
00456         return status;
00457     }
00458 
00459     info->lgrui0_name = (LPWSTR)((LPBYTE)info + sizeof(*info));
00460     lstrcpyW(info->lgrui0_name, admins);
00461 
00462     *bufptr = (LPBYTE)info;
00463     *entriesread = 1;
00464 
00465     return NERR_Success;
00466 }
00467 
00468 /************************************************************
00469  *                NetUserEnum  (NETAPI32.@)
00470  */
00471 NET_API_STATUS WINAPI
00472 NetUserEnum(LPCWSTR servername, DWORD level, DWORD filter, LPBYTE* bufptr,
00473         DWORD prefmaxlen, LPDWORD entriesread, LPDWORD totalentries,
00474         LPDWORD resume_handle)
00475 {
00476   FIXME("(%s,%d, 0x%d,%p,%d,%p,%p,%p) stub!\n", debugstr_w(servername), level,
00477         filter, bufptr, prefmaxlen, entriesread, totalentries, resume_handle);
00478 
00479   return ERROR_ACCESS_DENIED;
00480 }
00481 
00482 /************************************************************
00483  *                ACCESS_QueryAdminDisplayInformation
00484  *
00485  *  Creates a buffer with information for the Admin User
00486  */
00487 static void ACCESS_QueryAdminDisplayInformation(PNET_DISPLAY_USER *buf, PDWORD pdwSize)
00488 {
00489     static const WCHAR sAdminUserName[] = {
00490         'A','d','m','i','n','i','s','t','r','a','t','o','r',0};
00491 
00492     /* sizes of the field buffers in WCHARS */
00493     int name_sz, comment_sz, full_name_sz;
00494     PNET_DISPLAY_USER usr;
00495 
00496     /* set up buffer */
00497     name_sz = lstrlenW(sAdminUserName) + 1;
00498     comment_sz = 1;
00499     full_name_sz = 1;
00500     
00501     *pdwSize = sizeof(NET_DISPLAY_USER);
00502     *pdwSize += (name_sz + comment_sz + full_name_sz) * sizeof(WCHAR);
00503     NetApiBufferAllocate(*pdwSize, (LPVOID *) buf);
00504 
00505     usr = *buf;
00506     usr->usri1_name = (LPWSTR) ((PBYTE) usr + sizeof(NET_DISPLAY_USER));
00507     usr->usri1_comment = (LPWSTR) (
00508         ((PBYTE) usr->usri1_name) + name_sz * sizeof(WCHAR));
00509     usr->usri1_full_name = (LPWSTR) (
00510         ((PBYTE) usr->usri1_comment) + comment_sz * sizeof(WCHAR));
00511 
00512     /* set data */
00513     lstrcpyW(usr->usri1_name, sAdminUserName);
00514     usr->usri1_comment[0] = 0;
00515     usr->usri1_flags = UF_SCRIPT | UF_NORMAL_ACCOUNT | UF_DONT_EXPIRE_PASSWD;
00516     usr->usri1_full_name[0] = 0;
00517     usr->usri1_user_id = DOMAIN_USER_RID_ADMIN;
00518     usr->usri1_next_index = 0;
00519 }
00520 
00521 /************************************************************
00522  *                ACCESS_QueryGuestDisplayInformation
00523  *
00524  *  Creates a buffer with information for the Guest User
00525  */
00526 static void ACCESS_QueryGuestDisplayInformation(PNET_DISPLAY_USER *buf, PDWORD pdwSize)
00527 {
00528     static const WCHAR sGuestUserName[] = {
00529         'G','u','e','s','t',0 };
00530 
00531     /* sizes of the field buffers in WCHARS */
00532     int name_sz, comment_sz, full_name_sz;
00533     PNET_DISPLAY_USER usr;
00534 
00535     /* set up buffer */
00536     name_sz = lstrlenW(sGuestUserName) + 1;
00537     comment_sz = 1;
00538     full_name_sz = 1;
00539     
00540     *pdwSize = sizeof(NET_DISPLAY_USER);
00541     *pdwSize += (name_sz + comment_sz + full_name_sz) * sizeof(WCHAR);
00542     NetApiBufferAllocate(*pdwSize, (LPVOID *) buf);
00543 
00544     usr = *buf;
00545     usr->usri1_name = (LPWSTR) ((PBYTE) usr + sizeof(NET_DISPLAY_USER));
00546     usr->usri1_comment = (LPWSTR) (
00547         ((PBYTE) usr->usri1_name) + name_sz * sizeof(WCHAR));
00548     usr->usri1_full_name = (LPWSTR) (
00549         ((PBYTE) usr->usri1_comment) + comment_sz * sizeof(WCHAR));
00550 
00551     /* set data */
00552     lstrcpyW(usr->usri1_name, sGuestUserName);
00553     usr->usri1_comment[0] = 0;
00554     usr->usri1_flags = UF_ACCOUNTDISABLE | UF_SCRIPT | UF_NORMAL_ACCOUNT |
00555         UF_DONT_EXPIRE_PASSWD;
00556     usr->usri1_full_name[0] = 0;
00557     usr->usri1_user_id = DOMAIN_USER_RID_GUEST;
00558     usr->usri1_next_index = 0;
00559 }
00560 
00561 /************************************************************
00562  * Copies NET_DISPLAY_USER record.
00563  */
00564 static void ACCESS_CopyDisplayUser(const NET_DISPLAY_USER *dest, LPWSTR *dest_buf,
00565                             PNET_DISPLAY_USER src)
00566 {
00567     LPWSTR str = *dest_buf;
00568 
00569     src->usri1_name = str;
00570     lstrcpyW(src->usri1_name, dest->usri1_name);
00571     str = (LPWSTR) (
00572         ((PBYTE) str) + (lstrlenW(str) + 1) * sizeof(WCHAR));
00573 
00574     src->usri1_comment = str;
00575     lstrcpyW(src->usri1_comment, dest->usri1_comment);
00576     str = (LPWSTR) (
00577         ((PBYTE) str) + (lstrlenW(str) + 1) * sizeof(WCHAR));
00578 
00579     src->usri1_flags = dest->usri1_flags;
00580 
00581     src->usri1_full_name = str;
00582     lstrcpyW(src->usri1_full_name, dest->usri1_full_name);
00583     str = (LPWSTR) (
00584         ((PBYTE) str) + (lstrlenW(str) + 1) * sizeof(WCHAR));
00585 
00586     src->usri1_user_id = dest->usri1_user_id;
00587     src->usri1_next_index = dest->usri1_next_index;
00588     *dest_buf = str;
00589 }
00590 
00591 /************************************************************
00592  *                NetQueryDisplayInformation  (NETAPI32.@)
00593  *
00594  * The buffer structure:
00595  * - array of fixed size record of the level type
00596  * - strings, referenced by the record of the level type
00597  */
00598 NET_API_STATUS WINAPI
00599 NetQueryDisplayInformation(
00600     LPCWSTR ServerName, DWORD Level, DWORD Index, DWORD EntriesRequested,
00601     DWORD PreferredMaximumLength, LPDWORD ReturnedEntryCount,
00602     PVOID *SortedBuffer)
00603 {
00604     TRACE("(%s, %d, %d, %d, %d, %p, %p)\n", debugstr_w(ServerName),
00605           Level, Index, EntriesRequested, PreferredMaximumLength,
00606           ReturnedEntryCount, SortedBuffer);
00607 
00608     if(!NETAPI_IsLocalComputer(ServerName))
00609     {
00610         FIXME("Only implemented on local computer, but requested for "
00611               "remote server %s\n", debugstr_w(ServerName));
00612         return ERROR_ACCESS_DENIED;
00613     }
00614 
00615     switch (Level)
00616     {
00617     case 1:
00618     {
00619         /* current record */
00620         PNET_DISPLAY_USER inf;
00621         /* current available strings buffer */
00622         LPWSTR str;
00623         PNET_DISPLAY_USER admin, guest;
00624         DWORD admin_size, guest_size;
00625         LPWSTR name = NULL;
00626         DWORD dwSize;
00627 
00628         /* sizes of the field buffers in WCHARS */
00629         int name_sz, comment_sz, full_name_sz;
00630 
00631         /* number of the records, returned in SortedBuffer
00632            3 - for current user, Administrator and Guest users
00633          */
00634         int records = 3;
00635 
00636         FIXME("Level %d partially implemented\n", Level);
00637         *ReturnedEntryCount = records;
00638         comment_sz = 1;
00639         full_name_sz = 1;
00640 
00641         /* get data */
00642         dwSize = UNLEN + 1;
00643         NetApiBufferAllocate(dwSize * sizeof(WCHAR), (LPVOID *) &name);
00644         if (!GetUserNameW(name, &dwSize))
00645         {
00646             NetApiBufferFree(name);
00647             return ERROR_ACCESS_DENIED;
00648         }
00649         name_sz = dwSize;
00650         ACCESS_QueryAdminDisplayInformation(&admin, &admin_size);
00651         ACCESS_QueryGuestDisplayInformation(&guest, &guest_size);
00652 
00653         /* set up buffer */
00654         dwSize = sizeof(NET_DISPLAY_USER) * records;
00655         dwSize += (name_sz + comment_sz + full_name_sz) * sizeof(WCHAR);
00656 
00657         NetApiBufferAllocate(dwSize +
00658                              admin_size - sizeof(NET_DISPLAY_USER) +
00659                              guest_size - sizeof(NET_DISPLAY_USER),
00660                              SortedBuffer);
00661         inf = *SortedBuffer;
00662         str = (LPWSTR) ((PBYTE) inf + sizeof(NET_DISPLAY_USER) * records);
00663         inf->usri1_name = str;
00664         str = (LPWSTR) (
00665             ((PBYTE) str) + name_sz * sizeof(WCHAR));
00666         inf->usri1_comment = str;
00667         str = (LPWSTR) (
00668             ((PBYTE) str) + comment_sz * sizeof(WCHAR));
00669         inf->usri1_full_name = str;
00670         str = (LPWSTR) (
00671             ((PBYTE) str) + full_name_sz * sizeof(WCHAR));
00672 
00673         /* set data */
00674         lstrcpyW(inf->usri1_name, name);
00675         NetApiBufferFree(name);
00676         inf->usri1_comment[0] = 0;
00677         inf->usri1_flags =
00678             UF_SCRIPT | UF_NORMAL_ACCOUNT | UF_DONT_EXPIRE_PASSWD;
00679         inf->usri1_full_name[0] = 0;
00680         inf->usri1_user_id = 0;
00681         inf->usri1_next_index = 0;
00682 
00683         inf++;
00684         ACCESS_CopyDisplayUser(admin, &str, inf);
00685         NetApiBufferFree(admin);
00686 
00687         inf++;
00688         ACCESS_CopyDisplayUser(guest, &str, inf);
00689         NetApiBufferFree(guest);
00690         break;
00691     }
00692 
00693     case 2:
00694     case 3:
00695     {
00696         FIXME("Level %d is not implemented\n", Level);
00697         break;
00698     }
00699 
00700     default:
00701         TRACE("Invalid level %d is specified\n", Level);
00702         return ERROR_INVALID_LEVEL;
00703     }
00704     return NERR_Success;
00705 }
00706 
00707 /************************************************************
00708  *                NetGetDCName  (NETAPI32.@)
00709  *
00710  *  Return the name of the primary domain controller (PDC)
00711  */
00712 
00713 NET_API_STATUS WINAPI
00714 NetGetDCName(LPCWSTR servername, LPCWSTR domainname, LPBYTE *bufptr)
00715 {
00716   FIXME("(%s, %s, %p) stub!\n", debugstr_w(servername),
00717                  debugstr_w(domainname), bufptr);
00718   return NERR_DCNotFound; /* say we can't find a domain controller */  
00719 }
00720 
00721 /************************************************************
00722  *                NetGroupEnum  (NETAPI32.@)
00723  *
00724  */
00725 NET_API_STATUS WINAPI
00726 NetGroupEnum(LPCWSTR servername, DWORD level, LPBYTE *bufptr, DWORD prefmaxlen,
00727              LPDWORD entriesread, LPDWORD totalentries, LPDWORD resume_handle)
00728 {
00729     FIXME("(%s, %d, %p, %d, %p, %p, %p) stub!\n", debugstr_w(servername),
00730           level, bufptr, prefmaxlen, entriesread, totalentries, resume_handle);
00731     return ERROR_ACCESS_DENIED;
00732 }
00733 
00734 /************************************************************
00735  *                NetGroupGetInfo  (NETAPI32.@)
00736  *
00737  */
00738 NET_API_STATUS WINAPI NetGroupGetInfo(LPCWSTR servername, LPCWSTR groupname, DWORD level, LPBYTE *bufptr)
00739 {
00740     FIXME("(%s, %s, %d, %p) stub!\n", debugstr_w(servername), debugstr_w(groupname), level, bufptr);
00741     return ERROR_ACCESS_DENIED;
00742 }
00743 
00744 /******************************************************************************
00745  * NetUserModalsGet  (NETAPI32.@)
00746  *
00747  * Retrieves global information for all users and global groups in the security
00748  * database.
00749  *
00750  * PARAMS
00751  *  szServer   [I] Specifies the DNS or the NetBIOS name of the remote server
00752  *                 on which the function is to execute.
00753  *  level      [I] Information level of the data.
00754  *     0   Return global passwords parameters. bufptr points to a
00755  *         USER_MODALS_INFO_0 struct.
00756  *     1   Return logon server and domain controller information. bufptr
00757  *         points to a USER_MODALS_INFO_1 struct.
00758  *     2   Return domain name and identifier. bufptr points to a 
00759  *         USER_MODALS_INFO_2 struct.
00760  *     3   Return lockout information. bufptr points to a USER_MODALS_INFO_3
00761  *         struct.
00762  *  pbuffer    [I] Buffer that receives the data.
00763  *
00764  * RETURNS
00765  *  Success: NERR_Success.
00766  *  Failure: 
00767  *     ERROR_ACCESS_DENIED - the user does not have access to the info.
00768  *     NERR_InvalidComputer - computer name is invalid.
00769  */
00770 NET_API_STATUS WINAPI NetUserModalsGet(
00771     LPCWSTR szServer, DWORD level, LPBYTE *pbuffer)
00772 {
00773     TRACE("(%s %d %p)\n", debugstr_w(szServer), level, pbuffer);
00774     
00775     switch (level)
00776     {
00777         case 0:
00778             /* return global passwords parameters */
00779             FIXME("level 0 not implemented!\n");
00780             *pbuffer = NULL;
00781             return NERR_InternalError;
00782         case 1:
00783             /* return logon server and domain controller info */
00784             FIXME("level 1 not implemented!\n");
00785             *pbuffer = NULL;
00786             return NERR_InternalError;
00787         case 2:
00788         {
00789             /* return domain name and identifier */
00790             PUSER_MODALS_INFO_2 umi;
00791             LSA_HANDLE policyHandle;
00792             LSA_OBJECT_ATTRIBUTES objectAttributes;
00793             PPOLICY_ACCOUNT_DOMAIN_INFO domainInfo;
00794             NTSTATUS ntStatus;
00795             PSID domainIdentifier = NULL;
00796             int domainNameLen, domainIdLen;
00797 
00798             ZeroMemory(&objectAttributes, sizeof(objectAttributes));
00799             objectAttributes.Length = sizeof(objectAttributes);
00800 
00801             ntStatus = LsaOpenPolicy(NULL, &objectAttributes,
00802                                      POLICY_VIEW_LOCAL_INFORMATION,
00803                                      &policyHandle);
00804             if (ntStatus != STATUS_SUCCESS)
00805             {
00806                 WARN("LsaOpenPolicy failed with NT status %x\n",
00807                      LsaNtStatusToWinError(ntStatus));
00808                 return ntStatus;
00809             }
00810 
00811             ntStatus = LsaQueryInformationPolicy(policyHandle,
00812                                                  PolicyAccountDomainInformation,
00813                                                  (PVOID *)&domainInfo);
00814             if (ntStatus != STATUS_SUCCESS)
00815             {
00816                 WARN("LsaQueryInformationPolicy failed with NT status %x\n",
00817                      LsaNtStatusToWinError(ntStatus));
00818                 LsaClose(policyHandle);
00819                 return ntStatus;
00820             }
00821 
00822             domainIdentifier = domainInfo->DomainSid;
00823             domainIdLen = (domainIdentifier) ? GetLengthSid(domainIdentifier) : 0;
00824             domainNameLen = lstrlenW(domainInfo->DomainName.Buffer) + 1;
00825             LsaClose(policyHandle);
00826 
00827             ntStatus = NetApiBufferAllocate(sizeof(USER_MODALS_INFO_2) +
00828                                             domainIdLen +
00829                                             domainNameLen * sizeof(WCHAR),
00830                                             (LPVOID *)pbuffer);
00831 
00832             if (ntStatus != NERR_Success)
00833             {
00834                 WARN("NetApiBufferAllocate() failed\n");
00835                 LsaFreeMemory(domainInfo);
00836                 return ntStatus;
00837             }
00838 
00839             umi = (USER_MODALS_INFO_2 *) *pbuffer;
00840             umi->usrmod2_domain_id = (domainIdLen > 0) ? (*pbuffer + sizeof(USER_MODALS_INFO_2)) : NULL;
00841             umi->usrmod2_domain_name = (LPWSTR)(*pbuffer +
00842                 sizeof(USER_MODALS_INFO_2) + domainIdLen);
00843 
00844             lstrcpynW(umi->usrmod2_domain_name,
00845                       domainInfo->DomainName.Buffer,
00846                       domainNameLen);
00847             if (domainIdLen > 0)
00848                 CopySid(GetLengthSid(domainIdentifier), umi->usrmod2_domain_id,
00849                         domainIdentifier);
00850 
00851             LsaFreeMemory(domainInfo);
00852 
00853             break;
00854         } 
00855         case 3:
00856             /* return lockout information */
00857             FIXME("level 3 not implemented!\n");
00858             *pbuffer = NULL;
00859             return NERR_InternalError;
00860         default:
00861             TRACE("Invalid level %d is specified\n", level);
00862             *pbuffer = NULL;
00863             return ERROR_INVALID_LEVEL;
00864     }
00865 
00866     return NERR_Success;
00867 }
00868 
00869 /******************************************************************************
00870  *                NetUserChangePassword  (NETAPI32.@)
00871  * PARAMS
00872  *  domainname  [I] Optional. Domain on which the user resides or the logon
00873  *                  domain of the current user if NULL.
00874  *  username    [I] Optional. Username to change the password for or the name
00875  *                  of the current user if NULL.
00876  *  oldpassword [I] The user's current password.
00877  *  newpassword [I] The password that the user will be changed to using.
00878  *
00879  * RETURNS
00880  *  Success: NERR_Success.
00881  *  Failure: NERR_* failure code or win error code.
00882  *
00883  */
00884 NET_API_STATUS WINAPI NetUserChangePassword(LPCWSTR domainname, LPCWSTR username,
00885     LPCWSTR oldpassword, LPCWSTR newpassword)
00886 {
00887     struct sam_user *user;
00888 
00889     TRACE("(%s, %s, ..., ...)\n", debugstr_w(domainname), debugstr_w(username));
00890 
00891     if(domainname)
00892         FIXME("Ignoring domainname %s.\n", debugstr_w(domainname));
00893 
00894     if((user = NETAPI_FindUser(username)) == NULL)
00895         return NERR_UserNotFound;
00896 
00897     if(lstrcmpW(user->user_password, oldpassword) != 0)
00898         return ERROR_INVALID_PASSWORD;
00899 
00900     if(lstrlenW(newpassword) > PWLEN)
00901         return ERROR_PASSWORD_RESTRICTION;
00902 
00903     lstrcpyW(user->user_password, newpassword);
00904 
00905     return NERR_Success;
00906 }
00907 
00908 NET_API_STATUS WINAPI NetUseAdd(LMSTR servername, DWORD level, LPBYTE bufptr, LPDWORD parm_err)
00909 {
00910     FIXME("%s %d %p %p stub\n", debugstr_w(servername), level, bufptr, parm_err);
00911     return NERR_Success;
00912 }

Generated on Sun May 27 2012 04:20:50 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.