Something went wrong. Try again.
Reactos
Something went wrong. Try again.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094/* * Copyright 2002 Andriy Palamarchuk * * netapi32 user functions * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
/* * TODO: * Implement NetUserGetGroups (WIP) * Implement NetUserSetGroups * NetUserGetLocalGroups does not support LG_INCLUDE_INDIRECT yet. * Add missing information levels. * ... */
#include "netapi32.h"
#include <ndk/kefuncs.h>#include <ndk/obfuncs.h>
WINE_DEFAULT_DEBUG_CHANNEL(netapi32);
typedef struct _ENUM_CONTEXT{ LIST_ENTRY ListLink; ULONG EnumHandle;
SAM_HANDLE ServerHandle; SAM_HANDLE BuiltinDomainHandle; SAM_HANDLE AccountDomainHandle; PSID BuiltinDomainSid; PSID AccountDomainSid;
SAM_ENUMERATE_HANDLE EnumerationContext; PSAM_RID_ENUMERATION Buffer; ULONG Count; ULONG Index; BOOLEAN BuiltinDone;
} ENUM_CONTEXT, *PENUM_CONTEXT;
LIST_ENTRY g_EnumContextListHead;CRITICAL_SECTION g_EnumContextListLock;LONG g_EnumContextHandle = 0;
staticULONGDeltaTimeToSeconds(LARGE_INTEGER DeltaTime){ LARGE_INTEGER Seconds;
if (DeltaTime.QuadPart == 0) return 0;
Seconds.QuadPart = -DeltaTime.QuadPart / 10000000;
if (Seconds.HighPart != 0) return TIMEQ_FOREVER;
return Seconds.LowPart;}
staticNTSTATUSGetAllowedWorldAce(IN PACL Acl, OUT PACCESS_ALLOWED_ACE *Ace){ SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY}; ULONG WorldSid[sizeof(SID) / sizeof(ULONG) + SID_MAX_SUB_AUTHORITIES]; ACL_SIZE_INFORMATION AclSize; PVOID LocalAce = NULL; ULONG i; NTSTATUS Status;
*Ace = NULL;
RtlInitializeSid((PSID)WorldSid, &WorldAuthority, 1); *(RtlSubAuthoritySid((PSID)WorldSid, 0)) = SECURITY_WORLD_RID;
Status = RtlQueryInformationAcl(Acl, &AclSize, sizeof(AclSize), AclSizeInformation); if (!NT_SUCCESS(Status)) return Status;
for (i = 0; i < AclSize.AceCount; i++) { Status = RtlGetAce(Acl, i, &LocalAce); if (!NT_SUCCESS(Status)) return Status;
if (((PACE_HEADER)LocalAce)->AceType != ACCESS_ALLOWED_ACE_TYPE) continue;
if (RtlEqualSid((PSID)WorldSid, (PSID)&((PACCESS_ALLOWED_ACE)LocalAce)->SidStart)) { *Ace = (PACCESS_ALLOWED_ACE)LocalAce; return STATUS_SUCCESS; } }
return STATUS_SUCCESS;}
staticULONGGetAccountFlags(ULONG AccountControl, PACL Dacl){ PACCESS_ALLOWED_ACE Ace = NULL; ULONG Flags = UF_SCRIPT; NTSTATUS Status;
if (Dacl != NULL) { Status = GetAllowedWorldAce(Dacl, &Ace); if (NT_SUCCESS(Status)) { if (Ace == NULL) { Flags |= UF_PASSWD_CANT_CHANGE; } else if ((Ace->Mask & USER_CHANGE_PASSWORD) == 0) { Flags |= UF_PASSWD_CANT_CHANGE; } } }
if (AccountControl & USER_ACCOUNT_DISABLED) Flags |= UF_ACCOUNTDISABLE;
if (AccountControl & USER_HOME_DIRECTORY_REQUIRED) Flags |= UF_HOMEDIR_REQUIRED;
if (AccountControl & USER_PASSWORD_NOT_REQUIRED) Flags |= UF_PASSWD_NOTREQD;
if (AccountControl & USER_ACCOUNT_AUTO_LOCKED) Flags |= UF_LOCKOUT;
if (AccountControl & USER_DONT_EXPIRE_PASSWORD) Flags |= UF_DONT_EXPIRE_PASSWD;
/* if (AccountControl & USER_ENCRYPTED_TEXT_PASSWORD_ALLOWED) Flags |= UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED;
if (AccountControl & USER_SMARTCARD_REQUIRED) Flags |= UF_SMARTCARD_REQUIRED;
if (AccountControl & USER_TRUSTED_FOR_DELEGATION) Flags |= UF_TRUSTED_FOR_DELEGATION;
if (AccountControl & USER_NOT_DELEGATED) Flags |= UF_NOT_DELEGATED;
if (AccountControl & USER_USE_DES_KEY_ONLY) Flags |= UF_USE_DES_KEY_ONLY;
if (AccountControl & USER_DONT_REQUIRE_PREAUTH) Flags |= UF_DONT_REQUIRE_PREAUTH;
if (AccountControl & USER_PASSWORD_EXPIRED) Flags |= UF_PASSWORD_EXPIRED;*/
/* Set account type flags */ if (AccountControl & USER_TEMP_DUPLICATE_ACCOUNT) Flags |= UF_TEMP_DUPLICATE_ACCOUNT; else if (AccountControl & USER_NORMAL_ACCOUNT) Flags |= UF_NORMAL_ACCOUNT; else if (AccountControl & USER_INTERDOMAIN_TRUST_ACCOUNT) Flags |= UF_INTERDOMAIN_TRUST_ACCOUNT; else if (AccountControl & USER_WORKSTATION_TRUST_ACCOUNT) Flags |= UF_WORKSTATION_TRUST_ACCOUNT; else if (AccountControl & USER_SERVER_TRUST_ACCOUNT) Flags |= UF_SERVER_TRUST_ACCOUNT;
return Flags;}
staticULONGGetAccountControl(ULONG Flags){ ULONG AccountControl = 0;
if (Flags & UF_ACCOUNTDISABLE) AccountControl |= USER_ACCOUNT_DISABLED;
if (Flags & UF_HOMEDIR_REQUIRED) AccountControl |= USER_HOME_DIRECTORY_REQUIRED;
if (Flags & UF_PASSWD_NOTREQD) AccountControl |= USER_PASSWORD_NOT_REQUIRED;
if (Flags & UF_LOCKOUT) AccountControl |= USER_ACCOUNT_AUTO_LOCKED;
if (Flags & UF_DONT_EXPIRE_PASSWD) AccountControl |= USER_DONT_EXPIRE_PASSWORD;
/* Set account type flags */ if (Flags & UF_TEMP_DUPLICATE_ACCOUNT) AccountControl |= USER_TEMP_DUPLICATE_ACCOUNT; else if (Flags & UF_NORMAL_ACCOUNT) AccountControl |= USER_NORMAL_ACCOUNT; else if (Flags & UF_INTERDOMAIN_TRUST_ACCOUNT) AccountControl |= USER_INTERDOMAIN_TRUST_ACCOUNT; else if (Flags & UF_WORKSTATION_TRUST_ACCOUNT) AccountControl |= USER_WORKSTATION_TRUST_ACCOUNT; else if (Flags & UF_SERVER_TRUST_ACCOUNT) AccountControl |= USER_SERVER_TRUST_ACCOUNT;
return AccountControl;}
staticDWORDGetPasswordAge(IN PLARGE_INTEGER PasswordLastSet){ LARGE_INTEGER SystemTime; ULONG SystemSecondsSince1970; ULONG PasswordSecondsSince1970; NTSTATUS Status;
Status = NtQuerySystemTime(&SystemTime); if (!NT_SUCCESS(Status)) return 0;
RtlTimeToSecondsSince1970(&SystemTime, &SystemSecondsSince1970); RtlTimeToSecondsSince1970(PasswordLastSet, &PasswordSecondsSince1970);
return SystemSecondsSince1970 - PasswordSecondsSince1970;}
staticVOIDChangeUserDacl(IN PACL Dacl, IN ULONG Flags){ PACCESS_ALLOWED_ACE Ace = NULL; NTSTATUS Status;
if (Dacl == NULL) return;
Status = GetAllowedWorldAce(Dacl, &Ace); if (!NT_SUCCESS(Status)) return;
if (Flags & UF_PASSWD_CANT_CHANGE) Ace->Mask &= ~USER_CHANGE_PASSWORD; else Ace->Mask |= USER_CHANGE_PASSWORD;}
staticNET_API_STATUSGetUserDacl(IN SAM_HANDLE UserHandle, OUT PACL *Dacl){ PSECURITY_DESCRIPTOR SecurityDescriptor = NULL; PACL SamDacl; PACL LocalDacl; BOOLEAN Defaulted; BOOLEAN Present; ACL_SIZE_INFORMATION AclSize; NET_API_STATUS ApiStatus; NTSTATUS Status;
TRACE("(%p %p)\n", UserHandle, Dacl);
*Dacl = NULL;
Status = SamQuerySecurityObject(UserHandle, DACL_SECURITY_INFORMATION, &SecurityDescriptor); if (!NT_SUCCESS(Status)) { TRACE("SamQuerySecurityObject() failed (Status 0x%08lx)\n", Status); ApiStatus = NetpNtStatusToApiStatus(Status); goto done; }
Status = RtlGetDaclSecurityDescriptor(SecurityDescriptor, &Present, &SamDacl, &Defaulted); if (!NT_SUCCESS(Status)) { TRACE("RtlGetDaclSecurityDescriptor() failed (Status 0x%08lx)\n", Status); ApiStatus = NERR_InternalError; goto done; }
if (Present == FALSE) { TRACE("No DACL present\n"); ApiStatus = NERR_Success; goto done; }
Status = RtlQueryInformationAcl(SamDacl, &AclSize, sizeof(AclSize), AclSizeInformation); if (!NT_SUCCESS(Status)) { TRACE("RtlQueryInformationAcl() failed (Status 0x%08lx)\n", Status); ApiStatus = NERR_InternalError; goto done; }
LocalDacl = HeapAlloc(GetProcessHeap(), 0, AclSize.AclBytesInUse); if (LocalDacl == NULL) { TRACE("Memory allocation failed\n"); ApiStatus = ERROR_NOT_ENOUGH_MEMORY; goto done; }
RtlCopyMemory(LocalDacl, SamDacl, AclSize.AclBytesInUse);
*Dacl = LocalDacl;
ApiStatus = NERR_Success;
done: if (SecurityDescriptor != NULL) SamFreeMemory(SecurityDescriptor);
TRACE("done (ApiStatus: 0x%08lx)\n", ApiStatus);
return ApiStatus;}
staticVOIDFreeUserInfo(PUSER_ALL_INFORMATION UserInfo){ if (UserInfo->UserName.Buffer != NULL) SamFreeMemory(UserInfo->UserName.Buffer);
if (UserInfo->FullName.Buffer != NULL) SamFreeMemory(UserInfo->FullName.Buffer);
if (UserInfo->HomeDirectory.Buffer != NULL) SamFreeMemory(UserInfo->HomeDirectory.Buffer);
if (UserInfo->HomeDirectoryDrive.Buffer != NULL) SamFreeMemory(UserInfo->HomeDirectoryDrive.Buffer);
if (UserInfo->ScriptPath.Buffer != NULL) SamFreeMemory(UserInfo->ScriptPath.Buffer);
if (UserInfo->ProfilePath.Buffer != NULL) SamFreeMemory(UserInfo->ProfilePath.Buffer);
if (UserInfo->AdminComment.Buffer != NULL) SamFreeMemory(UserInfo->AdminComment.Buffer);
if (UserInfo->WorkStations.Buffer != NULL) SamFreeMemory(UserInfo->WorkStations.Buffer);
if (UserInfo->UserComment.Buffer != NULL) SamFreeMemory(UserInfo->UserComment.Buffer);
if (UserInfo->Parameters.Buffer != NULL) SamFreeMemory(UserInfo->Parameters.Buffer);
if (UserInfo->PrivateData.Buffer != NULL) SamFreeMemory(UserInfo->PrivateData.Buffer);
if (UserInfo->LogonHours.LogonHours != NULL) SamFreeMemory(UserInfo->LogonHours.LogonHours);
SamFreeMemory(UserInfo);}
staticNET_API_STATUSGetUserPrivileges( _In_ SAM_HANDLE BuiltinDomainHandle, _In_ SAM_HANDLE UserHandle, _In_ PSID AccountDomainSid, _In_ ULONG RelativeId, _Out_ PDWORD Priv, _Out_ PDWORD AuthFlags){ PGROUP_MEMBERSHIP GroupMembership = NULL; ULONG GroupCount, SidCount, AliasCount, i; PSID *SidArray = NULL; PULONG AliasArray = NULL; BOOL bAdmin = FALSE, bUser = FALSE; NET_API_STATUS ApiStatus = NERR_Success; NTSTATUS Status;
FIXME("GetUserPrivileges(%p)\n", UserHandle);
/* Get the users group memberships */ Status = SamGetGroupsForUser(UserHandle, &GroupMembership, &GroupCount); if (!NT_SUCCESS(Status)) { ERR("SamGetGroupsForUser() failed (Status 0x%08lx)\n", Status); ApiStatus = NetpNtStatusToApiStatus(Status); goto done; }
/* Allocate the SID array */ ApiStatus = NetApiBufferAllocate((GroupCount + 1) * sizeof(PSID), (PVOID*)&SidArray); if (ApiStatus != NERR_Success) { goto done; }
/* Add the user to the SID array */ SidCount = 0; ApiStatus = BuildSidFromSidAndRid(AccountDomainSid, RelativeId, &SidArray[0]); if (ApiStatus != NERR_Success) { goto done; }
SidCount++;
/* Add the groups to the SID array */ for (i = 0; i < GroupCount; i++) { ApiStatus = BuildSidFromSidAndRid(AccountDomainSid, GroupMembership[i].RelativeId, &SidArray[i + 1]); if (ApiStatus != NERR_Success) { goto done; }
SidCount++; }
/* Get aliases for the user and his groups */ Status = SamGetAliasMembership(BuiltinDomainHandle, SidCount, SidArray, &AliasCount, &AliasArray); if (!NT_SUCCESS(Status)) { ERR("SamGetAliasMembership() failed (Status 0x%08lx)\n", Status); ApiStatus = NetpNtStatusToApiStatus(Status); goto done; }
*AuthFlags = 0;
/* Set the AuthFlags */ for (i = 0; i < AliasCount; i++) { switch (AliasArray[i]) { case DOMAIN_ALIAS_RID_ADMINS: bAdmin = TRUE; break;
case DOMAIN_ALIAS_RID_USERS: bUser = TRUE; break;
case DOMAIN_ALIAS_RID_ACCOUNT_OPS: *AuthFlags |= AF_OP_ACCOUNTS; break;
case DOMAIN_ALIAS_RID_SYSTEM_OPS: *AuthFlags |= AF_OP_SERVER; break;
case DOMAIN_ALIAS_RID_PRINT_OPS: *AuthFlags |= AF_OP_PRINT; break; } }
/* Set the prvileges */ if (bAdmin) { *Priv = USER_PRIV_ADMIN; } else if (bUser) { *Priv = USER_PRIV_USER; } else { *Priv = USER_PRIV_GUEST; }
done: if (AliasArray != NULL) SamFreeMemory(AliasArray);
if (SidArray != NULL) { for (i = 0; i < SidCount; i++) NetApiBufferFree(SidArray[i]);
NetApiBufferFree(SidArray); }
if (GroupMembership != NULL) SamFreeMemory(GroupMembership);
return ApiStatus;}
staticNET_API_STATUSBuildUserInfoBuffer( _In_ SAM_HANDLE BuiltinDomainHandle, _In_ SAM_HANDLE UserHandle, _In_ PSID AccountDomainSid, _In_ ULONG RelativeId, _In_ DWORD level, _Out_ LPVOID *Buffer){ UNICODE_STRING LogonServer = RTL_CONSTANT_STRING(L"\\\\*"); PUSER_ALL_INFORMATION UserInfo = NULL; LPVOID LocalBuffer = NULL; PACL Dacl = NULL; DWORD Priv = 0, AuthFlags = 0; PUSER_INFO_0 UserInfo0; PUSER_INFO_1 UserInfo1; PUSER_INFO_2 UserInfo2; PUSER_INFO_3 UserInfo3; PUSER_INFO_4 UserInfo4; PUSER_INFO_10 UserInfo10; PUSER_INFO_11 UserInfo11; PUSER_INFO_20 UserInfo20; PUSER_INFO_23 UserInfo23; LPWSTR Ptr; ULONG Size = 0; NTSTATUS Status; NET_API_STATUS ApiStatus = NERR_Success;
*Buffer = NULL;
Status = SamQueryInformationUser(UserHandle, UserAllInformation, (PVOID *)&UserInfo); if (!NT_SUCCESS(Status)) { ERR("SamQueryInformationUser failed (Status %08lx)\n", Status); ApiStatus = NetpNtStatusToApiStatus(Status); goto done; }
if ((level == 1) || (level == 2) || (level == 3) || (level == 4) || (level == 20) || (level == 23)) { ApiStatus = GetUserDacl(UserHandle, &Dacl); if (ApiStatus != NERR_Success) goto done; }
if ((level == 1) || (level == 2) || (level == 3) || (level == 4) || (level == 11)) { ApiStatus = GetUserPrivileges(BuiltinDomainHandle, UserHandle, AccountDomainSid, RelativeId, &Priv, &AuthFlags); if (ApiStatus != NERR_Success) goto done; }
switch (level) { case 0: Size = sizeof(USER_INFO_0) + UserInfo->UserName.Length + sizeof(WCHAR); break;
case 1: Size = sizeof(USER_INFO_1) + UserInfo->UserName.Length + sizeof(WCHAR) + UserInfo->HomeDirectory.Length + sizeof(WCHAR) + UserInfo->AdminComment.Length + sizeof(WCHAR) + UserInfo->ScriptPath.Length + sizeof(WCHAR); break;
case 2: Size = sizeof(USER_INFO_2) + UserInfo->UserName.Length + sizeof(WCHAR) + UserInfo->HomeDirectory.Length + sizeof(WCHAR) + UserInfo->AdminComment.Length + sizeof(WCHAR) + UserInfo->ScriptPath.Length + sizeof(WCHAR) + UserInfo->FullName.Length + sizeof(WCHAR) + UserInfo->UserComment.Length + sizeof(WCHAR) + UserInfo->Parameters.Length + sizeof(WCHAR) + UserInfo->WorkStations.Length + sizeof(WCHAR) + LogonServer.Length + sizeof(WCHAR);
if (UserInfo->LogonHours.UnitsPerWeek > 0) Size += (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8; break;
case 3: Size = sizeof(USER_INFO_3) + UserInfo->UserName.Length + sizeof(WCHAR) + UserInfo->HomeDirectory.Length + sizeof(WCHAR) + UserInfo->AdminComment.Length + sizeof(WCHAR) + UserInfo->ScriptPath.Length + sizeof(WCHAR) + UserInfo->FullName.Length + sizeof(WCHAR) + UserInfo->UserComment.Length + sizeof(WCHAR) + UserInfo->Parameters.Length + sizeof(WCHAR) + UserInfo->WorkStations.Length + sizeof(WCHAR) + LogonServer.Length + sizeof(WCHAR) + UserInfo->ProfilePath.Length + sizeof(WCHAR) + UserInfo->HomeDirectoryDrive.Length + sizeof(WCHAR);
if (UserInfo->LogonHours.UnitsPerWeek > 0) Size += (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8; break;
case 4: Size = sizeof(USER_INFO_4) + UserInfo->UserName.Length + sizeof(WCHAR) + UserInfo->HomeDirectory.Length + sizeof(WCHAR) + UserInfo->AdminComment.Length + sizeof(WCHAR) + UserInfo->ScriptPath.Length + sizeof(WCHAR) + UserInfo->FullName.Length + sizeof(WCHAR) + UserInfo->UserComment.Length + sizeof(WCHAR) + UserInfo->Parameters.Length + sizeof(WCHAR) + UserInfo->WorkStations.Length + sizeof(WCHAR) + LogonServer.Length + sizeof(WCHAR) + UserInfo->ProfilePath.Length + sizeof(WCHAR) + UserInfo->HomeDirectoryDrive.Length + sizeof(WCHAR);
if (UserInfo->LogonHours.UnitsPerWeek > 0) Size += (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8;
Size += RtlLengthSid(AccountDomainSid) + sizeof(ULONG); break;
case 10: Size = sizeof(USER_INFO_10) + UserInfo->UserName.Length + sizeof(WCHAR) + UserInfo->AdminComment.Length + sizeof(WCHAR) + UserInfo->UserComment.Length + sizeof(WCHAR) + UserInfo->FullName.Length + sizeof(WCHAR); break;
case 11: Size = sizeof(USER_INFO_11) + UserInfo->UserName.Length + sizeof(WCHAR) + UserInfo->AdminComment.Length + sizeof(WCHAR) + UserInfo->UserComment.Length + sizeof(WCHAR) + UserInfo->FullName.Length + sizeof(WCHAR) + UserInfo->HomeDirectory.Length + sizeof(WCHAR) + UserInfo->Parameters.Length + sizeof(WCHAR) + LogonServer.Length + sizeof(WCHAR) + UserInfo->WorkStations.Length + sizeof(WCHAR);
if (UserInfo->LogonHours.UnitsPerWeek > 0) Size += (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8; break;
case 20: Size = sizeof(USER_INFO_20) + UserInfo->UserName.Length + sizeof(WCHAR) + UserInfo->FullName.Length + sizeof(WCHAR) + UserInfo->AdminComment.Length + sizeof(WCHAR); break;
case 23: Size = sizeof(USER_INFO_23) + UserInfo->UserName.Length + sizeof(WCHAR) + UserInfo->FullName.Length + sizeof(WCHAR) + UserInfo->AdminComment.Length + sizeof(WCHAR);
Size += RtlLengthSid(AccountDomainSid) + sizeof(ULONG); break;
default: ApiStatus = ERROR_INVALID_LEVEL; goto done; }
ApiStatus = NetApiBufferAllocate(Size, &LocalBuffer); if (ApiStatus != NERR_Success) goto done;
ZeroMemory(LocalBuffer, Size);
switch (level) { case 0: UserInfo0 = (PUSER_INFO_0)LocalBuffer;
Ptr = (LPWSTR)((ULONG_PTR)UserInfo0 + sizeof(USER_INFO_0));
UserInfo0->usri0_name = Ptr;
memcpy(UserInfo0->usri0_name, UserInfo->UserName.Buffer, UserInfo->UserName.Length); UserInfo0->usri0_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL; break;
case 1: UserInfo1 = (PUSER_INFO_1)LocalBuffer;
Ptr = (LPWSTR)((ULONG_PTR)UserInfo1 + sizeof(USER_INFO_1));
UserInfo1->usri1_name = Ptr;
memcpy(UserInfo1->usri1_name, UserInfo->UserName.Buffer, UserInfo->UserName.Length); UserInfo1->usri1_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL;
Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserName.Length + sizeof(WCHAR));
UserInfo1->usri1_password = NULL; UserInfo1->usri1_password_age = GetPasswordAge(&UserInfo->PasswordLastSet);
UserInfo1->usri1_priv = Priv;
UserInfo1->usri1_home_dir = Ptr; memcpy(UserInfo1->usri1_home_dir, UserInfo->HomeDirectory.Buffer, UserInfo->HomeDirectory.Length); UserInfo1->usri1_home_dir[UserInfo->HomeDirectory.Length / sizeof(WCHAR)] = UNICODE_NULL; Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->HomeDirectory.Length + sizeof(WCHAR));
UserInfo1->usri1_comment = Ptr; memcpy(UserInfo1->usri1_comment, UserInfo->AdminComment.Buffer, UserInfo->AdminComment.Length); UserInfo1->usri1_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL; Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR));
UserInfo1->usri1_flags = GetAccountFlags(UserInfo->UserAccountControl, Dacl);
UserInfo1->usri1_script_path = Ptr; memcpy(UserInfo1->usri1_script_path, UserInfo->ScriptPath.Buffer, UserInfo->ScriptPath.Length); UserInfo1->usri1_script_path[UserInfo->ScriptPath.Length / sizeof(WCHAR)] = UNICODE_NULL; break;
case 2: UserInfo2 = (PUSER_INFO_2)LocalBuffer;
Ptr = (LPWSTR)((ULONG_PTR)UserInfo2 + sizeof(USER_INFO_2));
UserInfo2->usri2_name = Ptr;
memcpy(UserInfo2->usri2_name, UserInfo->UserName.Buffer, UserInfo->UserName.Length); UserInfo2->usri2_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL;
Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserName.Length + sizeof(WCHAR));
UserInfo2->usri2_password = NULL; UserInfo2->usri2_password_age = GetPasswordAge(&UserInfo->PasswordLastSet);
UserInfo2->usri2_priv = Priv;
UserInfo2->usri2_home_dir = Ptr; memcpy(UserInfo2->usri2_home_dir, UserInfo->HomeDirectory.Buffer, UserInfo->HomeDirectory.Length); UserInfo2->usri2_home_dir[UserInfo->HomeDirectory.Length / sizeof(WCHAR)] = UNICODE_NULL; Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->HomeDirectory.Length + sizeof(WCHAR));
UserInfo2->usri2_comment = Ptr; memcpy(UserInfo2->usri2_comment, UserInfo->AdminComment.Buffer, UserInfo->AdminComment.Length); UserInfo2->usri2_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL; Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR));
UserInfo2->usri2_flags = GetAccountFlags(UserInfo->UserAccountControl, Dacl);
UserInfo2->usri2_script_path = Ptr; memcpy(UserInfo2->usri2_script_path, UserInfo->ScriptPath.Buffer, UserInfo->ScriptPath.Length); UserInfo2->usri2_script_path[UserInfo->ScriptPath.Length / sizeof(WCHAR)] = UNICODE_NULL; Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->ScriptPath.Length + sizeof(WCHAR));
UserInfo2->usri2_auth_flags = AuthFlags;
UserInfo2->usri2_full_name = Ptr; memcpy(UserInfo2->usri2_full_name, UserInfo->FullName.Buffer, UserInfo->FullName.Length); UserInfo2->usri2_full_name[UserInfo->FullName.Length / sizeof(WCHAR)] = UNICODE_NULL; Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->FullName.Length + sizeof(WCHAR));
UserInfo2->usri2_usr_comment = Ptr; memcpy(UserInfo2->usri2_usr_comment, UserInfo->UserComment.Buffer, UserInfo->UserComment.Length); UserInfo2->usri2_usr_comment[UserInfo->UserComment.Length / sizeof(WCHAR)] = UNICODE_NULL; Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserComment.Length + sizeof(WCHAR));
UserInfo2->usri2_parms = Ptr; memcpy(UserInfo2->usri2_parms, UserInfo->Parameters.Buffer, UserInfo->Parameters.Length); UserInfo2->usri2_parms[UserInfo->Parameters.Length / sizeof(WCHAR)] = UNICODE_NULL; Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->Parameters.Length + sizeof(WCHAR));
UserInfo2->usri2_workstations = Ptr; memcpy(UserInfo2->usri2_workstations, UserInfo->WorkStations.Buffer, UserInfo->WorkStations.Length); UserInfo2->usri2_workstations[UserInfo->WorkStations.Length / sizeof(WCHAR)] = UNICODE_NULL; Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->WorkStations.Length + sizeof(WCHAR));
if (UserInfo->LastLogon.QuadPart == 0) UserInfo2->usri2_last_logon = 0; else RtlTimeToSecondsSince1970(&UserInfo->LastLogon, &UserInfo2->usri2_last_logon);
if (UserInfo->LastLogoff.QuadPart == 0) UserInfo2->usri2_last_logoff = 0; else RtlTimeToSecondsSince1970(&UserInfo->LastLogoff, &UserInfo2->usri2_last_logoff);
if (UserInfo->AccountExpires.QuadPart == MAXLONGLONG) UserInfo2->usri2_acct_expires = TIMEQ_FOREVER; else RtlTimeToSecondsSince1970(&UserInfo->AccountExpires, &UserInfo2->usri2_acct_expires);
UserInfo2->usri2_max_storage = USER_MAXSTORAGE_UNLIMITED; UserInfo2->usri2_units_per_week = UserInfo->LogonHours.UnitsPerWeek;
if (UserInfo->LogonHours.UnitsPerWeek > 0) { UserInfo2->usri2_logon_hours = (PVOID)Ptr;
memcpy(UserInfo2->usri2_logon_hours, UserInfo->LogonHours.LogonHours, (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8);
Ptr = (LPWSTR)((ULONG_PTR)Ptr + (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8); }
UserInfo2->usri2_bad_pw_count = UserInfo->BadPasswordCount; UserInfo2->usri2_num_logons = UserInfo->LogonCount;
UserInfo2->usri2_logon_server = Ptr; memcpy(UserInfo2->usri2_logon_server, LogonServer.Buffer, LogonServer.Length); UserInfo2->usri2_logon_server[LogonServer.Length / sizeof(WCHAR)] = UNICODE_NULL; Ptr = (LPWSTR)((ULONG_PTR)Ptr + LogonServer.Length + sizeof(WCHAR));
UserInfo2->usri2_country_code = UserInfo->CountryCode; UserInfo2->usri2_code_page = UserInfo->CodePage; break;
case 3: UserInfo3 = (PUSER_INFO_3)LocalBuffer;
Ptr = (LPWSTR)((ULONG_PTR)UserInfo3 + sizeof(USER_INFO_3));
UserInfo3->usri3_name = Ptr;
memcpy(UserInfo3->usri3_name, UserInfo->UserName.Buffer, UserInfo->UserName.Length); UserInfo3->usri3_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL;
Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserName.Length + sizeof(WCHAR));
UserInfo3->usri3_password = NULL; UserInfo3->usri3_password_age = GetPasswordAge(&UserInfo->PasswordLastSet);
UserInfo3->usri3_priv = Priv;
UserInfo3->usri3_home_dir = Ptr; memcpy(UserInfo3->usri3_home_dir, UserInfo->HomeDirectory.Buffer, UserInfo->HomeDirectory.Length); UserInfo3->usri3_home_dir[UserInfo->HomeDirectory.Length / sizeof(WCHAR)] = UNICODE_NULL; Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->HomeDirectory.Length + sizeof(WCHAR));
UserInfo3->usri3_comment = Ptr; memcpy(UserInfo3->usri3_comment, UserInfo->AdminComment.Buffer, UserInfo->AdminComment.Length); UserInfo3->usri3_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL; Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR));
UserInfo3->usri3_flags = GetAccountFlags(UserInfo->UserAccountControl, Dacl);
UserInfo3->usri3_script_path = Ptr; memcpy(UserInfo3->usri3_script_path, UserInfo->ScriptPath.Buffer, UserInfo->ScriptPath.Length); UserInfo3->usri3_script_path[UserInfo->ScriptPath.Length / sizeof(WCHAR)] = UNICODE_NULL; Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->ScriptPath.Length + sizeof(WCHAR));
UserInfo3->usri3_auth_flags = AuthFlags;
UserInfo3->usri3_full_name = Ptr; memcpy(UserInfo3->usri3_full_name, UserInfo->FullName.Buffer, UserInfo->FullName.Length); UserInfo3->usri3_full_name[UserInfo->FullName.Length / sizeof(WCHAR)] = UNICODE_NULL; Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->FullName.Length + sizeof(WCHAR));
UserInfo3->usri3_usr_comment = Ptr; memcpy(UserInfo3->usri3_usr_comment, UserInfo->UserComment.Buffer, UserInfo->UserComment.Length); UserInfo3->usri3_usr_comment[UserInfo->UserComment.Length / sizeof(WCHAR)] = UNICODE_NULL; Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserComment.Length + sizeof(WCHAR));
UserInfo3->usri3_parms = Ptr; memcpy(UserInfo3->usri3_parms, UserInfo->Parameters.Buffer, UserInfo->Parameters.Length); UserInfo3->usri3_parms[UserInfo->Parameters.Length / sizeof(WCHAR)] = UNICODE_NULL; Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->Parameters.Length + sizeof(WCHAR));
UserInfo3->usri3_workstations = Ptr; memcpy(UserInfo3->usri3_workstations, UserInfo->WorkStations.Buffer, UserInfo->WorkStations.Length); UserInfo3->usri3_workstations[UserInfo->WorkStations.Length / sizeof(WCHAR)] = UNICODE_NULL; Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->WorkStations.Length + sizeof(WCHAR));
if (UserInfo->LastLogon.QuadPart == 0) UserInfo3->usri3_last_logon = 0; else RtlTimeToSecondsSince1970(&UserInfo->LastLogon, &UserInfo3->usri3_last_logon);
if (UserInfo->LastLogoff.QuadPart == 0) UserInfo3->usri3_last_logoff = 0; else RtlTimeToSecondsSince1970(&UserInfo->LastLogoff, &UserInfo3->usri3_last_logoff);
if (UserInfo->AccountExpires.QuadPart == MAXLONGLONG) UserInfo3->usri3_acct_expires = TIMEQ_FOREVER; else RtlTimeToSecondsSince1970(&UserInfo->AccountExpires, &UserInfo3->usri3_acct_expires);
UserInfo3->usri3_max_storage = USER_MAXSTORAGE_UNLIMITED; UserInfo3->usri3_units_per_week = UserInfo->LogonHours.UnitsPerWeek;
if (UserInfo->LogonHours.UnitsPerWeek > 0) { UserInfo3->usri3_logon_hours = (PVOID)Ptr;
memcpy(UserInfo3->usri3_logon_hours, UserInfo->LogonHours.LogonHours, (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8);
Ptr = (LPWSTR)((ULONG_PTR)Ptr + (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8); }
UserInfo3->usri3_bad_pw_count = UserInfo->BadPasswordCount; UserInfo3->usri3_num_logons = UserInfo->LogonCount;
UserInfo3->usri3_logon_server = Ptr; memcpy(UserInfo3->usri3_logon_server, LogonServer.Buffer, LogonServer.Length); UserInfo3->usri3_logon_server[LogonServer.Length / sizeof(WCHAR)] = UNICODE_NULL; Ptr = (LPWSTR)((ULONG_PTR)Ptr + LogonServer.Length + sizeof(WCHAR));
UserInfo3->usri3_country_code = UserInfo->CountryCode; UserInfo3->usri3_code_page = UserInfo->CodePage; UserInfo3->usri3_user_id = RelativeId; UserInfo3->usri3_primary_group_id = UserInfo->PrimaryGroupId;
UserInfo3->usri3_profile = Ptr; memcpy(UserInfo3->usri3_profile, UserInfo->ProfilePath.Buffer, UserInfo->ProfilePath.Length); UserInfo3->usri3_profile[UserInfo->ProfilePath.Length / sizeof(WCHAR)] = UNICODE_NULL; Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->ProfilePath.Length + sizeof(WCHAR));
UserInfo3->usri3_home_dir_drive = Ptr; memcpy(UserInfo3->usri3_home_dir_drive, UserInfo->HomeDirectoryDrive.Buffer, UserInfo->HomeDirectoryDrive.Length); UserInfo3->usri3_home_dir_drive[UserInfo->HomeDirectoryDrive.Length / sizeof(WCHAR)] = UNICODE_NULL; Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->HomeDirectoryDrive.Length + sizeof(WCHAR));
UserInfo3->usri3_password_expired = (UserInfo->UserAccountControl & USER_PASSWORD_EXPIRED); break;
case 4: UserInfo4 = (PUSER_INFO_4)LocalBuffer;
Ptr = (LPWSTR)((ULONG_PTR)UserInfo4 + sizeof(USER_INFO_4));
UserInfo4->usri4_name = Ptr;
memcpy(UserInfo4->usri4_name, UserInfo->UserName.Buffer, UserInfo->UserName.Length); UserInfo4->usri4_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL;
Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserName.Length + sizeof(WCHAR));
UserInfo4->usri4_password = NULL; UserInfo4->usri4_password_age = GetPasswordAge(&UserInfo->PasswordLastSet);
UserInfo4->usri4_priv = Priv;
UserInfo4->usri4_home_dir = Ptr; memcpy(UserInfo4->usri4_home_dir, UserInfo->HomeDirectory.Buffer, UserInfo->HomeDirectory.Length); UserInfo4->usri4_home_dir[UserInfo->HomeDirectory.Length / sizeof(WCHAR)] = UNICODE_NULL; Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->HomeDirectory.Length + sizeof(WCHAR));
UserInfo4->usri4_comment = Ptr; memcpy(UserInfo4->usri4_comment, UserInfo->AdminComment.Buffer, UserInfo->AdminComment.Length); UserInfo4->usri4_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL; Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR));
UserInfo4->usri4_flags = GetAccountFlags(UserInfo->UserAccountControl, Dacl);
UserInfo4->usri4_script_path = Ptr; memcpy(UserInfo4->usri4_script_path, UserInfo->ScriptPath.Buffer, UserInfo->ScriptPath.Length); UserInfo4->usri4_script_path[UserInfo->ScriptPath.Length / sizeof(WCHAR)] = UNICODE_NULL; Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->ScriptPath.Length + sizeof(WCHAR));
UserInfo4->usri4_auth_flags = AuthFlags;
UserInfo4->usri4_full_name = Ptr; memcpy(UserInfo4->usri4_full_name, UserInfo->FullName.Buffer, UserInfo->FullName.Length); UserInfo4->usri4_full_name[UserInfo->FullName.Length / sizeof(WCHAR)] = UNICODE_NULL; Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->FullName.Length + sizeof(WCHAR));
UserInfo4->usri4_usr_comment = Ptr; memcpy(UserInfo4->usri4_usr_comment, UserInfo->UserComment.Buffer, UserInfo->UserComment.Length); UserInfo4->usri4_usr_comment[UserInfo->UserComment.Length / sizeof(WCHAR)] = UNICODE_NULL; Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserComment.Length + sizeof(WCHAR));
UserInfo4->usri4_parms = Ptr; memcpy(UserInfo4->usri4_parms, UserInfo->Parameters.Buffer, UserInfo->Parameters.Length); UserInfo4->usri4_parms[UserInfo->Parameters.Length / sizeof(WCHAR)] = UNICODE_NULL; Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->Parameters.Length + sizeof(WCHAR));
UserInfo4->usri4_workstations = Ptr; memcpy(UserInfo4->usri4_workstations, UserInfo->WorkStations.Buffer, UserInfo->WorkStations.Length); UserInfo4->usri4_workstations[UserInfo->WorkStations.Length / sizeof(WCHAR)] = UNICODE_NULL; Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->WorkStations.Length + sizeof(WCHAR));
if (UserInfo->LastLogon.QuadPart == 0) UserInfo4->usri4_last_logon = 0; else RtlTimeToSecondsSince1970(&UserInfo->LastLogon, &UserInfo4->usri4_last_logon);
if (UserInfo->LastLogoff.QuadPart == 0) UserInfo4->usri4_last_logoff = 0; else RtlTimeToSecondsSince1970(&UserInfo->LastLogoff, &UserInfo4->usri4_last_logoff);
if (UserInfo->AccountExpires.QuadPart == MAXLONGLONG) UserInfo4->usri4_acct_expires = TIMEQ_FOREVER; else RtlTimeToSecondsSince1970(&UserInfo->AccountExpires, &UserInfo4->usri4_acct_expires);
UserInfo4->usri4_max_storage = USER_MAXSTORAGE_UNLIMITED; UserInfo4->usri4_units_per_week = UserInfo->LogonHours.UnitsPerWeek;
if (UserInfo->LogonHours.UnitsPerWeek > 0) { UserInfo4->usri4_logon_hours = (PVOID)Ptr;
memcpy(UserInfo4->usri4_logon_hours, UserInfo->LogonHours.LogonHours, (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8);
Ptr = (LPWSTR)((ULONG_PTR)Ptr + (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8); }
UserInfo4->usri4_bad_pw_count = UserInfo->BadPasswordCount; UserInfo4->usri4_num_logons = UserInfo->LogonCount;
UserInfo4->usri4_logon_server = Ptr; memcpy(UserInfo4->usri4_logon_server, LogonServer.Buffer, LogonServer.Length); UserInfo4->usri4_logon_server[LogonServer.Length / sizeof(WCHAR)] = UNICODE_NULL; Ptr = (LPWSTR)((ULONG_PTR)Ptr + LogonServer.Length + sizeof(WCHAR));
UserInfo4->usri4_country_code = UserInfo->CountryCode; UserInfo4->usri4_code_page = UserInfo->CodePage;
UserInfo4->usri4_user_sid = (PVOID)Ptr; CopySidFromSidAndRid(UserInfo4->usri4_user_sid, AccountDomainSid, RelativeId); Ptr = (LPWSTR)((ULONG_PTR)Ptr + RtlLengthSid(AccountDomainSid) + sizeof(ULONG));
UserInfo4->usri4_primary_group_id = UserInfo->PrimaryGroupId;
UserInfo4->usri4_profile = Ptr; memcpy(UserInfo4->usri4_profile, UserInfo->ProfilePath.Buffer, UserInfo->ProfilePath.Length); UserInfo4->usri4_profile[UserInfo->ProfilePath.Length / sizeof(WCHAR)] = UNICODE_NULL; Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->ProfilePath.Length + sizeof(WCHAR));
UserInfo4->usri4_home_dir_drive = Ptr; memcpy(UserInfo4->usri4_home_dir_drive, UserInfo->HomeDirectoryDrive.Buffer, UserInfo->HomeDirectoryDrive.Length); UserInfo4->usri4_home_dir_drive[UserInfo->HomeDirectoryDrive.Length / sizeof(WCHAR)] = UNICODE_NULL; Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->HomeDirectoryDrive.Length + sizeof(WCHAR));
UserInfo4->usri4_password_expired = (UserInfo->UserAccountControl & USER_PASSWORD_EXPIRED); break;
case 10: UserInfo10 = (PUSER_INFO_10)LocalBuffer;
Ptr = (LPWSTR)((ULONG_PTR)UserInfo10 + sizeof(USER_INFO_10));
UserInfo10->usri10_name = Ptr;
memcpy(UserInfo10->usri10_name, UserInfo->UserName.Buffer, UserInfo->UserName.Length); UserInfo10->usri10_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL;
Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserName.Length + sizeof(WCHAR));
UserInfo10->usri10_comment = Ptr; memcpy(UserInfo10->usri10_comment, UserInfo->AdminComment.Buffer, UserInfo->AdminComment.Length); UserInfo10->usri10_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL; Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR));
UserInfo10->usri10_usr_comment = Ptr; memcpy(UserInfo10->usri10_usr_comment, UserInfo->UserComment.Buffer, UserInfo->UserComment.Length); UserInfo10->usri10_usr_comment[UserInfo->UserComment.Length / sizeof(WCHAR)] = UNICODE_NULL; Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserComment.Length + sizeof(WCHAR));
UserInfo10->usri10_full_name = Ptr; memcpy(UserInfo10->usri10_full_name, UserInfo->FullName.Buffer, UserInfo->FullName.Length); UserInfo10->usri10_full_name[UserInfo->FullName.Length / sizeof(WCHAR)] = UNICODE_NULL; break;
case 11: UserInfo11 = (PUSER_INFO_11)LocalBuffer;
Ptr = (LPWSTR)((ULONG_PTR)UserInfo11 + sizeof(USER_INFO_11));
UserInfo11->usri11_name = Ptr;
memcpy(UserInfo11->usri11_name, UserInfo->UserName.Buffer, UserInfo->UserName.Length); UserInfo11->usri11_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL;
Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserName.Length + sizeof(WCHAR));
UserInfo11->usri11_comment = Ptr; memcpy(UserInfo11->usri11_comment, UserInfo->AdminComment.Buffer, UserInfo->AdminComment.Length); UserInfo11->usri11_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL; Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR));
UserInfo11->usri11_usr_comment = Ptr; memcpy(UserInfo11->usri11_usr_comment, UserInfo->UserComment.Buffer, UserInfo->UserComment.Length); UserInfo11->usri11_usr_comment[UserInfo->UserComment.Length / sizeof(WCHAR)] = UNICODE_NULL; Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserComment.Length + sizeof(WCHAR));
UserInfo11->usri11_full_name = Ptr; memcpy(UserInfo11->usri11_full_name, UserInfo->FullName.Buffer, UserInfo->FullName.Length); UserInfo11->usri11_full_name[UserInfo->FullName.Length / sizeof(WCHAR)] = UNICODE_NULL; Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->FullName.Length + sizeof(WCHAR));
UserInfo11->usri11_priv = Priv; UserInfo11->usri11_auth_flags = AuthFlags;
UserInfo11->usri11_password_age = GetPasswordAge(&UserInfo->PasswordLastSet);
UserInfo11->usri11_home_dir = Ptr; memcpy(UserInfo11->usri11_home_dir, UserInfo->HomeDirectory.Buffer, UserInfo->HomeDirectory.Length); UserInfo11->usri11_home_dir[UserInfo->HomeDirectory.Length / sizeof(WCHAR)] = UNICODE_NULL; Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->HomeDirectory.Length + sizeof(WCHAR));
UserInfo11->usri11_parms = Ptr; memcpy(UserInfo11->usri11_parms, UserInfo->Parameters.Buffer, UserInfo->Parameters.Length); UserInfo11->usri11_parms[UserInfo->Parameters.Length / sizeof(WCHAR)] = UNICODE_NULL; Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->Parameters.Length + sizeof(WCHAR));
if (UserInfo->LastLogon.QuadPart == 0) UserInfo11->usri11_last_logon = 0; else RtlTimeToSecondsSince1970(&UserInfo->LastLogon, &UserInfo11->usri11_last_logon);
if (UserInfo->LastLogoff.QuadPart == 0) UserInfo11->usri11_last_logoff = 0; else RtlTimeToSecondsSince1970(&UserInfo->LastLogoff, &UserInfo11->usri11_last_logoff);
UserInfo11->usri11_bad_pw_count = UserInfo->BadPasswordCount; UserInfo11->usri11_num_logons = UserInfo->LogonCount;
UserInfo11->usri11_logon_server = Ptr; memcpy(UserInfo11->usri11_logon_server, LogonServer.Buffer, LogonServer.Length); UserInfo11->usri11_logon_server[LogonServer.Length / sizeof(WCHAR)] = UNICODE_NULL; Ptr = (LPWSTR)((ULONG_PTR)Ptr + LogonServer.Length + sizeof(WCHAR));
UserInfo11->usri11_country_code = UserInfo->CountryCode;
UserInfo11->usri11_workstations = Ptr; memcpy(UserInfo11->usri11_workstations, UserInfo->WorkStations.Buffer, UserInfo->WorkStations.Length); UserInfo11->usri11_workstations[UserInfo->WorkStations.Length / sizeof(WCHAR)] = UNICODE_NULL; Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->WorkStations.Length + sizeof(WCHAR));
UserInfo11->usri11_max_storage = USER_MAXSTORAGE_UNLIMITED; UserInfo11->usri11_units_per_week = UserInfo->LogonHours.UnitsPerWeek;
if (UserInfo->LogonHours.UnitsPerWeek > 0) { UserInfo11->usri11_logon_hours = (PVOID)Ptr;
memcpy(UserInfo11->usri11_logon_hours, UserInfo->LogonHours.LogonHours, (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8);
Ptr = (LPWSTR)((ULONG_PTR)Ptr + (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8); }
UserInfo11->usri11_code_page = UserInfo->CodePage; break;
case 20: UserInfo20 = (PUSER_INFO_20)LocalBuffer;
Ptr = (LPWSTR)((ULONG_PTR)UserInfo20 + sizeof(USER_INFO_20));
UserInfo20->usri20_name = Ptr;
memcpy(UserInfo20->usri20_name, UserInfo->UserName.Buffer, UserInfo->UserName.Length); UserInfo20->usri20_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL;
Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserName.Length + sizeof(WCHAR));
UserInfo20->usri20_full_name = Ptr; memcpy(UserInfo20->usri20_full_name, UserInfo->FullName.Buffer, UserInfo->FullName.Length); UserInfo20->usri20_full_name[UserInfo->FullName.Length / sizeof(WCHAR)] = UNICODE_NULL; Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->FullName.Length + sizeof(WCHAR));
UserInfo20->usri20_comment = Ptr; memcpy(UserInfo20->usri20_comment, UserInfo->AdminComment.Buffer, UserInfo->AdminComment.Length); UserInfo20->usri20_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL; Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR));
UserInfo20->usri20_flags = GetAccountFlags(UserInfo->UserAccountControl, Dacl);
UserInfo20->usri20_user_id = RelativeId; break;
case 23: UserInfo23 = (PUSER_INFO_23)LocalBuffer;
Ptr = (LPWSTR)((ULONG_PTR)UserInfo23 + sizeof(USER_INFO_23));
UserInfo23->usri23_name = Ptr;
memcpy(UserInfo23->usri23_name, UserInfo->UserName.Buffer, UserInfo->UserName.Length); UserInfo23->usri23_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL;
Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserName.Length + sizeof(WCHAR));
UserInfo23->usri23_full_name = Ptr; memcpy(UserInfo23->usri23_full_name, UserInfo->FullName.Buffer, UserInfo->FullName.Length); UserInfo23->usri23_full_name[UserInfo->FullName.Length / sizeof(WCHAR)] = UNICODE_NULL; Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->FullName.Length + sizeof(WCHAR));
UserInfo23->usri23_comment = Ptr; memcpy(UserInfo23->usri23_comment, UserInfo->AdminComment.Buffer, UserInfo->AdminComment.Length); UserInfo23->usri23_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL; Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR));
UserInfo23->usri23_flags = GetAccountFlags(UserInfo->UserAccountControl, Dacl);
UserInfo23->usri23_user_sid = (PVOID)Ptr; CopySidFromSidAndRid(UserInfo23->usri23_user_sid, AccountDomainSid, RelativeId); Ptr = (LPWSTR)((ULONG_PTR)Ptr + RtlLengthSid(AccountDomainSid) + sizeof(ULONG)); break; }
done: if (UserInfo != NULL) FreeUserInfo(UserInfo);
if (Dacl != NULL) HeapFree(GetProcessHeap(), 0, Dacl);
if (ApiStatus == NERR_Success) { *Buffer = LocalBuffer; } else { if (LocalBuffer != NULL) NetApiBufferFree(LocalBuffer); }
return ApiStatus;}
staticNET_API_STATUSSetUserInfo(SAM_HANDLE UserHandle, LPBYTE UserInfo, DWORD Level, PDWORD parm_err){ USER_ALL_INFORMATION UserAllInfo; PUSER_INFO_0 UserInfo0; PUSER_INFO_1 UserInfo1; PUSER_INFO_2 UserInfo2; PUSER_INFO_3 UserInfo3; PUSER_INFO_4 UserInfo4; PUSER_INFO_22 UserInfo22; PUSER_INFO_1003 UserInfo1003; PUSER_INFO_1006 UserInfo1006; PUSER_INFO_1007 UserInfo1007; PUSER_INFO_1008 UserInfo1008; PUSER_INFO_1009 UserInfo1009; PUSER_INFO_1011 UserInfo1011; PUSER_INFO_1012 UserInfo1012; PUSER_INFO_1013 UserInfo1013; PUSER_INFO_1014 UserInfo1014; PUSER_INFO_1017 UserInfo1017; PUSER_INFO_1020 UserInfo1020; PUSER_INFO_1024 UserInfo1024; PUSER_INFO_1025 UserInfo1025; PUSER_INFO_1051 UserInfo1051; PUSER_INFO_1052 UserInfo1052; PUSER_INFO_1053 UserInfo1053; PACL Dacl = NULL; NET_API_STATUS ApiStatus = NERR_Success; NTSTATUS Status = STATUS_SUCCESS;
ZeroMemory(&UserAllInfo, sizeof(USER_ALL_INFORMATION));
if ((Level == 1) || (Level == 2) || (Level == 3) || (Level == 4) || (Level == 22) || (Level == 1008)) { ApiStatus = GetUserDacl(UserHandle, &Dacl); if (ApiStatus != NERR_Success) goto done; }
switch (Level) { case 0: UserInfo0 = (PUSER_INFO_0)UserInfo;
RtlInitUnicodeString(&UserAllInfo.UserName, UserInfo0->usri0_name);
UserAllInfo.WhichFields |= USER_ALL_USERNAME; break;
case 1: UserInfo1 = (PUSER_INFO_1)UserInfo;
// usri1_name ignored
if (UserInfo1->usri1_password != NULL) { RtlInitUnicodeString(&UserAllInfo.NtPassword, UserInfo1->usri1_password); UserAllInfo.NtPasswordPresent = TRUE; UserAllInfo.WhichFields |= USER_ALL_NTPASSWORDPRESENT; }
// usri1_password_age ignored
// UserInfo1->usri1_priv
if (UserInfo1->usri1_home_dir != NULL) { RtlInitUnicodeString(&UserAllInfo.HomeDirectory, UserInfo1->usri1_home_dir); UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORY; }
if (UserInfo1->usri1_comment != NULL) { RtlInitUnicodeString(&UserAllInfo.AdminComment, UserInfo1->usri1_comment); UserAllInfo.WhichFields |= USER_ALL_ADMINCOMMENT; }
ChangeUserDacl(Dacl, UserInfo1->usri1_flags); UserAllInfo.UserAccountControl = GetAccountControl(UserInfo1->usri1_flags); UserAllInfo.WhichFields |= USER_ALL_USERACCOUNTCONTROL;
if (UserInfo1->usri1_script_path != NULL) { RtlInitUnicodeString(&UserAllInfo.ScriptPath, UserInfo1->usri1_script_path); UserAllInfo.WhichFields |= USER_ALL_SCRIPTPATH; } break;
case 2: UserInfo2 = (PUSER_INFO_2)UserInfo;
// usri2_name ignored
if (UserInfo2->usri2_password != NULL) { RtlInitUnicodeString(&UserAllInfo.NtPassword, UserInfo2->usri2_password); UserAllInfo.NtPasswordPresent = TRUE; UserAllInfo.WhichFields |= USER_ALL_NTPASSWORDPRESENT; }
// usri2_password_age ignored
// UserInfo2->usri2_priv;
if (UserInfo2->usri2_home_dir != NULL) { RtlInitUnicodeString(&UserAllInfo.HomeDirectory, UserInfo2->usri2_home_dir); UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORY; }
if (UserInfo2->usri2_comment != NULL) { RtlInitUnicodeString(&UserAllInfo.AdminComment, UserInfo2->usri2_comment); UserAllInfo.WhichFields |= USER_ALL_ADMINCOMMENT; }
ChangeUserDacl(Dacl, UserInfo2->usri2_flags); UserAllInfo.UserAccountControl = GetAccountControl(UserInfo2->usri2_flags); UserAllInfo.WhichFields |= USER_ALL_USERACCOUNTCONTROL;
if (UserInfo2->usri2_script_path != NULL) { RtlInitUnicodeString(&UserAllInfo.ScriptPath, UserInfo2->usri2_script_path); UserAllInfo.WhichFields |= USER_ALL_SCRIPTPATH; }
// UserInfo2->usri2_auth_flags;
if (UserInfo2->usri2_full_name != NULL) { RtlInitUnicodeString(&UserAllInfo.FullName, UserInfo2->usri2_full_name); UserAllInfo.WhichFields |= USER_ALL_FULLNAME; }
if (UserInfo2->usri2_usr_comment != NULL) { RtlInitUnicodeString(&UserAllInfo.UserComment, UserInfo2->usri2_usr_comment); UserAllInfo.WhichFields |= USER_ALL_USERCOMMENT; }
if (UserInfo2->usri2_parms != NULL) { RtlInitUnicodeString(&UserAllInfo.Parameters, UserInfo2->usri2_parms); UserAllInfo.WhichFields |= USER_ALL_PARAMETERS; }
if (UserInfo2->usri2_workstations != NULL) { RtlInitUnicodeString(&UserAllInfo.WorkStations, UserInfo2->usri2_workstations); UserAllInfo.WhichFields |= USER_ALL_WORKSTATIONS; }
// usri2_last_logon ignored // usri2_last_logoff ignored
if (UserInfo2->usri2_acct_expires == TIMEQ_FOREVER) { UserAllInfo.AccountExpires.QuadPart = MAXLONGLONG; } else { RtlSecondsSince1970ToTime(UserInfo2->usri2_acct_expires, &UserAllInfo.AccountExpires); } UserAllInfo.WhichFields |= USER_ALL_ACCOUNTEXPIRES;
// usri2_max_storage ignored
if (UserInfo2->usri2_logon_hours != NULL) { if (UserInfo2->usri2_units_per_week > USHRT_MAX) { if (parm_err != NULL) *parm_err = USER_UNITS_PER_WEEK_PARMNUM; ApiStatus = ERROR_INVALID_PARAMETER; break; }
UserAllInfo.LogonHours.UnitsPerWeek = UserInfo2->usri2_units_per_week; UserAllInfo.LogonHours.LogonHours = UserInfo2->usri2_logon_hours; UserAllInfo.WhichFields |= USER_ALL_LOGONHOURS; }
// usri2_bad_pw_count ignored // usri2_num_logons ignored // usri2_logon_server ignored
UserAllInfo.CountryCode = UserInfo2->usri2_country_code; UserAllInfo.WhichFields |= USER_ALL_COUNTRYCODE;
UserAllInfo.CodePage = UserInfo2->usri2_code_page; UserAllInfo.WhichFields |= USER_ALL_CODEPAGE; break;
case 3: UserInfo3 = (PUSER_INFO_3)UserInfo;
// usri3_name ignored
if (UserInfo3->usri3_password != NULL) { RtlInitUnicodeString(&UserAllInfo.NtPassword, UserInfo3->usri3_password); UserAllInfo.NtPasswordPresent = TRUE; UserAllInfo.WhichFields |= USER_ALL_NTPASSWORDPRESENT; }
// usri3_password_age ignored
// UserInfo3->usri3_priv;
if (UserInfo3->usri3_home_dir != NULL) { RtlInitUnicodeString(&UserAllInfo.HomeDirectory, UserInfo3->usri3_home_dir); UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORY; }
if (UserInfo3->usri3_comment != NULL) { RtlInitUnicodeString(&UserAllInfo.AdminComment, UserInfo3->usri3_comment); UserAllInfo.WhichFields |= USER_ALL_ADMINCOMMENT; }
ChangeUserDacl(Dacl, UserInfo3->usri3_flags); UserAllInfo.UserAccountControl = GetAccountControl(UserInfo3->usri3_flags); UserAllInfo.WhichFields |= USER_ALL_USERACCOUNTCONTROL;
if (UserInfo3->usri3_script_path != NULL) { RtlInitUnicodeString(&UserAllInfo.ScriptPath, UserInfo3->usri3_script_path); UserAllInfo.WhichFields |= USER_ALL_SCRIPTPATH; }
// UserInfo3->usri3_auth_flags;
if (UserInfo3->usri3_full_name != NULL) { RtlInitUnicodeString(&UserAllInfo.FullName, UserInfo3->usri3_full_name); UserAllInfo.WhichFields |= USER_ALL_FULLNAME; }
if (UserInfo3->usri3_usr_comment != NULL) { RtlInitUnicodeString(&UserAllInfo.UserComment, UserInfo3->usri3_usr_comment); UserAllInfo.WhichFields |= USER_ALL_USERCOMMENT; }
if (UserInfo3->usri3_parms != NULL) { RtlInitUnicodeString(&UserAllInfo.Parameters, UserInfo3->usri3_parms); UserAllInfo.WhichFields |= USER_ALL_PARAMETERS; }
if (UserInfo3->usri3_workstations != NULL) { RtlInitUnicodeString(&UserAllInfo.WorkStations, UserInfo3->usri3_workstations); UserAllInfo.WhichFields |= USER_ALL_WORKSTATIONS; }
// usri3_last_logon ignored // usri3_last_logoff ignored
if (UserInfo3->usri3_acct_expires == TIMEQ_FOREVER) { UserAllInfo.AccountExpires.QuadPart = MAXLONGLONG; } else { RtlSecondsSince1970ToTime(UserInfo3->usri3_acct_expires, &UserAllInfo.AccountExpires); } UserAllInfo.WhichFields |= USER_ALL_ACCOUNTEXPIRES;
// usri3_max_storage ignored
if (UserInfo3->usri3_logon_hours != NULL) { if (UserInfo3->usri3_units_per_week > USHRT_MAX) { if (parm_err != NULL) *parm_err = USER_UNITS_PER_WEEK_PARMNUM; ApiStatus = ERROR_INVALID_PARAMETER; break; }
UserAllInfo.LogonHours.UnitsPerWeek = UserInfo3->usri3_units_per_week; UserAllInfo.LogonHours.LogonHours = UserInfo3->usri3_logon_hours; UserAllInfo.WhichFields |= USER_ALL_LOGONHOURS; }
// usri3_bad_pw_count ignored // usri3_num_logons ignored // usri3_logon_server ignored
UserAllInfo.CountryCode = UserInfo3->usri3_country_code; UserAllInfo.WhichFields |= USER_ALL_COUNTRYCODE;
UserAllInfo.CodePage = UserInfo3->usri3_code_page; UserAllInfo.WhichFields |= USER_ALL_CODEPAGE;
// usri3_user_id ignored
UserAllInfo.PrimaryGroupId = UserInfo3->usri3_primary_group_id; UserAllInfo.WhichFields |= USER_ALL_PRIMARYGROUPID;
if (UserInfo3->usri3_profile != NULL) { RtlInitUnicodeString(&UserAllInfo.ProfilePath, UserInfo3->usri3_profile); UserAllInfo.WhichFields |= USER_ALL_PROFILEPATH; }
if (UserInfo3->usri3_home_dir_drive != NULL) { RtlInitUnicodeString(&UserAllInfo.HomeDirectoryDrive, UserInfo3->usri3_home_dir_drive); UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORYDRIVE; }
UserAllInfo.PasswordExpired = (UserInfo3->usri3_password_expired != 0); UserAllInfo.WhichFields |= USER_ALL_PASSWORDEXPIRED; break;
case 4: UserInfo4 = (PUSER_INFO_4)UserInfo;
// usri4_name ignored
if (UserInfo4->usri4_password != NULL) { RtlInitUnicodeString(&UserAllInfo.NtPassword, UserInfo4->usri4_password); UserAllInfo.NtPasswordPresent = TRUE; UserAllInfo.WhichFields |= USER_ALL_NTPASSWORDPRESENT; }
// usri4_password_age ignored
// UserInfo3->usri4_priv;
if (UserInfo4->usri4_home_dir != NULL) { RtlInitUnicodeString(&UserAllInfo.HomeDirectory, UserInfo4->usri4_home_dir); UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORY; }
if (UserInfo4->usri4_comment != NULL) { RtlInitUnicodeString(&UserAllInfo.AdminComment, UserInfo4->usri4_comment); UserAllInfo.WhichFields |= USER_ALL_ADMINCOMMENT; }
ChangeUserDacl(Dacl, UserInfo4->usri4_flags); UserAllInfo.UserAccountControl = GetAccountControl(UserInfo4->usri4_flags); UserAllInfo.WhichFields |= USER_ALL_USERACCOUNTCONTROL;
if (UserInfo4->usri4_script_path != NULL) { RtlInitUnicodeString(&UserAllInfo.ScriptPath, UserInfo4->usri4_script_path); UserAllInfo.WhichFields |= USER_ALL_SCRIPTPATH; }
// UserInfo4->usri4_auth_flags;
if (UserInfo4->usri4_full_name != NULL) { RtlInitUnicodeString(&UserAllInfo.FullName, UserInfo4->usri4_full_name); UserAllInfo.WhichFields |= USER_ALL_FULLNAME; }
if (UserInfo4->usri4_usr_comment != NULL) { RtlInitUnicodeString(&UserAllInfo.UserComment, UserInfo4->usri4_usr_comment); UserAllInfo.WhichFields |= USER_ALL_USERCOMMENT; }
if (UserInfo4->usri4_parms != NULL) { RtlInitUnicodeString(&UserAllInfo.Parameters, UserInfo4->usri4_parms); UserAllInfo.WhichFields |= USER_ALL_PARAMETERS; }
if (UserInfo4->usri4_workstations != NULL) { RtlInitUnicodeString(&UserAllInfo.WorkStations, UserInfo4->usri4_workstations); UserAllInfo.WhichFields |= USER_ALL_WORKSTATIONS; }
// usri4_last_logon ignored // usri4_last_logoff ignored
if (UserInfo4->usri4_acct_expires == TIMEQ_FOREVER) { UserAllInfo.AccountExpires.QuadPart = MAXLONGLONG; } else { RtlSecondsSince1970ToTime(UserInfo4->usri4_acct_expires, &UserAllInfo.AccountExpires); } UserAllInfo.WhichFields |= USER_ALL_ACCOUNTEXPIRES;
// usri4_max_storage ignored
if (UserInfo4->usri4_logon_hours != NULL) { if (UserInfo4->usri4_units_per_week > USHRT_MAX) { if (parm_err != NULL) *parm_err = USER_UNITS_PER_WEEK_PARMNUM; ApiStatus = ERROR_INVALID_PARAMETER; break; }
UserAllInfo.LogonHours.UnitsPerWeek = UserInfo4->usri4_units_per_week; UserAllInfo.LogonHours.LogonHours = UserInfo4->usri4_logon_hours; UserAllInfo.WhichFields |= USER_ALL_LOGONHOURS; }
// usri4_bad_pw_count ignored // usri4_num_logons ignored // usri4_logon_server ignored
UserAllInfo.CountryCode = UserInfo4->usri4_country_code; UserAllInfo.WhichFields |= USER_ALL_COUNTRYCODE;
UserAllInfo.CodePage = UserInfo4->usri4_code_page; UserAllInfo.WhichFields |= USER_ALL_CODEPAGE;
// usri4_user_sid ignored
UserAllInfo.PrimaryGroupId = UserInfo4->usri4_primary_group_id; UserAllInfo.WhichFields |= USER_ALL_PRIMARYGROUPID;
if (UserInfo4->usri4_profile != NULL) { RtlInitUnicodeString(&UserAllInfo.ProfilePath, UserInfo4->usri4_profile); UserAllInfo.WhichFields |= USER_ALL_PROFILEPATH; }
if (UserInfo4->usri4_home_dir_drive != NULL) { RtlInitUnicodeString(&UserAllInfo.HomeDirectoryDrive, UserInfo4->usri4_home_dir_drive); UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORYDRIVE; }
UserAllInfo.PasswordExpired = (UserInfo4->usri4_password_expired != 0); UserAllInfo.WhichFields |= USER_ALL_PASSWORDEXPIRED; break;
// case 21:// break;
case 22: UserInfo22 = (PUSER_INFO_22)UserInfo;
// usri22_name ignored
// UserInfo22->usri22_password[ENCRYPTED_PWLEN];
// usri22_password_age ignored
// UserInfo3->usri3_priv;
if (UserInfo22->usri22_home_dir != NULL) { RtlInitUnicodeString(&UserAllInfo.HomeDirectory, UserInfo22->usri22_home_dir); UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORY; }
if (UserInfo22->usri22_comment != NULL) { RtlInitUnicodeString(&UserAllInfo.AdminComment, UserInfo22->usri22_comment); UserAllInfo.WhichFields |= USER_ALL_ADMINCOMMENT; }
ChangeUserDacl(Dacl, UserInfo22->usri22_flags); UserAllInfo.UserAccountControl = GetAccountControl(UserInfo22->usri22_flags); UserAllInfo.WhichFields |= USER_ALL_USERACCOUNTCONTROL;
if (UserInfo22->usri22_script_path != NULL) { RtlInitUnicodeString(&UserAllInfo.ScriptPath, UserInfo22->usri22_script_path); UserAllInfo.WhichFields |= USER_ALL_SCRIPTPATH; }
// UserInfo22->usri22_auth_flags;
if (UserInfo22->usri22_full_name != NULL) { RtlInitUnicodeString(&UserAllInfo.FullName, UserInfo22->usri22_full_name); UserAllInfo.WhichFields |= USER_ALL_FULLNAME; }
if (UserInfo22->usri22_usr_comment != NULL) { RtlInitUnicodeString(&UserAllInfo.UserComment, UserInfo22->usri22_usr_comment); UserAllInfo.WhichFields |= USER_ALL_USERCOMMENT; }
if (UserInfo22->usri22_parms != NULL) { RtlInitUnicodeString(&UserAllInfo.Parameters, UserInfo22->usri22_parms); UserAllInfo.WhichFields |= USER_ALL_PARAMETERS; }
if (UserInfo22->usri22_workstations != NULL) { RtlInitUnicodeString(&UserAllInfo.WorkStations, UserInfo22->usri22_workstations); UserAllInfo.WhichFields |= USER_ALL_WORKSTATIONS; }
// usri22_last_logon ignored // usri22_last_logoff ignored
if (UserInfo22->usri22_acct_expires == TIMEQ_FOREVER) { UserAllInfo.AccountExpires.QuadPart = MAXLONGLONG; } else { RtlSecondsSince1970ToTime(UserInfo22->usri22_acct_expires, &UserAllInfo.AccountExpires); } UserAllInfo.WhichFields |= USER_ALL_ACCOUNTEXPIRES;
// usri22_max_storage ignored
if (UserInfo22->usri22_logon_hours != NULL) { if (UserInfo22->usri22_units_per_week > USHRT_MAX) { if (parm_err != NULL) *parm_err = USER_UNITS_PER_WEEK_PARMNUM; ApiStatus = ERROR_INVALID_PARAMETER; break; }
UserAllInfo.LogonHours.UnitsPerWeek = UserInfo22->usri22_units_per_week; UserAllInfo.LogonHours.LogonHours = UserInfo22->usri22_logon_hours; UserAllInfo.WhichFields |= USER_ALL_LOGONHOURS; }
// usri22_bad_pw_count ignored // usri22_num_logons ignored // usri22_logon_server ignored
UserAllInfo.CountryCode = UserInfo22->usri22_country_code; UserAllInfo.WhichFields |= USER_ALL_COUNTRYCODE;
UserAllInfo.CodePage = UserInfo22->usri22_code_page; UserAllInfo.WhichFields |= USER_ALL_CODEPAGE; break;
case 1003: UserInfo1003 = (PUSER_INFO_1003)UserInfo;
if (UserInfo1003->usri1003_password != NULL) { RtlInitUnicodeString(&UserAllInfo.NtPassword, UserInfo1003->usri1003_password); UserAllInfo.NtPasswordPresent = TRUE; UserAllInfo.WhichFields |= USER_ALL_NTPASSWORDPRESENT; } break;
// case 1005:// break;
case 1006: UserInfo1006 = (PUSER_INFO_1006)UserInfo;
if (UserInfo1006->usri1006_home_dir != NULL) { RtlInitUnicodeString(&UserAllInfo.HomeDirectory, UserInfo1006->usri1006_home_dir); UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORY; } break;
case 1007: UserInfo1007 = (PUSER_INFO_1007)UserInfo;
if (UserInfo1007->usri1007_comment != NULL) { RtlInitUnicodeString(&UserAllInfo.AdminComment, UserInfo1007->usri1007_comment); UserAllInfo.WhichFields |= USER_ALL_ADMINCOMMENT; } break;
case 1008: UserInfo1008 = (PUSER_INFO_1008)UserInfo; ChangeUserDacl(Dacl, UserInfo1008->usri1008_flags); UserAllInfo.UserAccountControl = GetAccountControl(UserInfo1008->usri1008_flags); UserAllInfo.WhichFields |= USER_ALL_USERACCOUNTCONTROL; break;
case 1009: UserInfo1009 = (PUSER_INFO_1009)UserInfo;
if (UserInfo1009->usri1009_script_path != NULL) { RtlInitUnicodeString(&UserAllInfo.ScriptPath, UserInfo1009->usri1009_script_path); UserAllInfo.WhichFields |= USER_ALL_SCRIPTPATH; } break;
// case 1010:// break;
case 1011: UserInfo1011 = (PUSER_INFO_1011)UserInfo;
if (UserInfo1011->usri1011_full_name != NULL) { RtlInitUnicodeString(&UserAllInfo.FullName, UserInfo1011->usri1011_full_name); UserAllInfo.WhichFields |= USER_ALL_FULLNAME; } break;
case 1012: UserInfo1012 = (PUSER_INFO_1012)UserInfo;
if (UserInfo1012->usri1012_usr_comment != NULL) { RtlInitUnicodeString(&UserAllInfo.UserComment, UserInfo1012->usri1012_usr_comment); UserAllInfo.WhichFields |= USER_ALL_USERCOMMENT; } break;
case 1013: UserInfo1013 = (PUSER_INFO_1013)UserInfo;
if (UserInfo1013->usri1013_parms != NULL) { RtlInitUnicodeString(&UserAllInfo.Parameters, UserInfo1013->usri1013_parms); UserAllInfo.WhichFields |= USER_ALL_PARAMETERS; } break;
case 1014: UserInfo1014 = (PUSER_INFO_1014)UserInfo;
if (UserInfo1014->usri1014_workstations != NULL) { RtlInitUnicodeString(&UserAllInfo.WorkStations, UserInfo1014->usri1014_workstations); UserAllInfo.WhichFields |= USER_ALL_WORKSTATIONS; } break;
case 1017: UserInfo1017 = (PUSER_INFO_1017)UserInfo;
if (UserInfo1017->usri1017_acct_expires == TIMEQ_FOREVER) { UserAllInfo.AccountExpires.QuadPart = MAXLONGLONG; } else { RtlSecondsSince1970ToTime(UserInfo1017->usri1017_acct_expires, &UserAllInfo.AccountExpires); } UserAllInfo.WhichFields |= USER_ALL_ACCOUNTEXPIRES; break;
case 1018: // usri1018_max_storage ignored break;
case 1020: UserInfo1020 = (PUSER_INFO_1020)UserInfo;
if (UserInfo1020->usri1020_logon_hours != NULL) { if (UserInfo1020->usri1020_units_per_week > USHRT_MAX) { if (parm_err != NULL) *parm_err = USER_UNITS_PER_WEEK_PARMNUM; ApiStatus = ERROR_INVALID_PARAMETER; break; }
UserAllInfo.LogonHours.UnitsPerWeek = UserInfo1020->usri1020_units_per_week; UserAllInfo.LogonHours.LogonHours = UserInfo1020->usri1020_logon_hours; UserAllInfo.WhichFields |= USER_ALL_LOGONHOURS; } break;
case 1024: UserInfo1024 = (PUSER_INFO_1024)UserInfo;
UserAllInfo.CountryCode = UserInfo1024->usri1024_country_code; UserAllInfo.WhichFields |= USER_ALL_COUNTRYCODE; break;
case 1025: UserInfo1025 = (PUSER_INFO_1025)UserInfo;
UserAllInfo.CodePage = UserInfo1025->usri1025_code_page; UserAllInfo.WhichFields |= USER_ALL_CODEPAGE; break;
case 1051: UserInfo1051 = (PUSER_INFO_1051)UserInfo;
UserAllInfo.PrimaryGroupId = UserInfo1051->usri1051_primary_group_id; UserAllInfo.WhichFields |= USER_ALL_PRIMARYGROUPID; break;
case 1052: UserInfo1052 = (PUSER_INFO_1052)UserInfo;
if (UserInfo1052->usri1052_profile != NULL) { RtlInitUnicodeString(&UserAllInfo.ProfilePath, UserInfo1052->usri1052_profile); UserAllInfo.WhichFields |= USER_ALL_PROFILEPATH; } break;
case 1053: UserInfo1053 = (PUSER_INFO_1053)UserInfo;
if (UserInfo1053->usri1053_home_dir_drive != NULL) { RtlInitUnicodeString(&UserAllInfo.HomeDirectoryDrive, UserInfo1053->usri1053_home_dir_drive); UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORYDRIVE; } break; }
if (ApiStatus != NERR_Success) goto done;
Status = SamSetInformationUser(UserHandle, UserAllInformation, &UserAllInfo); if (!NT_SUCCESS(Status)) { ERR("SamSetInformationUser failed (Status %08lx)\n", Status); ApiStatus = NetpNtStatusToApiStatus(Status); goto done; }
done: if (Dacl != NULL) HeapFree(GetProcessHeap(), 0, Dacl);
return ApiStatus;}
staticNET_API_STATUSOpenUserByName(SAM_HANDLE DomainHandle, PUNICODE_STRING UserName, ULONG DesiredAccess, PSAM_HANDLE UserHandle){ PULONG RelativeIds = NULL; PSID_NAME_USE Use = NULL; NET_API_STATUS ApiStatus = NERR_Success; NTSTATUS Status = STATUS_SUCCESS;
/* Get the RID for the given user name */ Status = SamLookupNamesInDomain(DomainHandle, 1, UserName, &RelativeIds, &Use); if (!NT_SUCCESS(Status)) { ERR("SamLookupNamesInDomain(%wZ) failed (Status %08lx)\n", UserName, Status); return NetpNtStatusToApiStatus(Status); }
/* Fail, if it is not an alias account */ if (Use[0] != SidTypeUser) { ERR("Object is not a user!\n"); ApiStatus = NERR_GroupNotFound; goto done; }
/* Open the alias account */ Status = SamOpenUser(DomainHandle, DesiredAccess, RelativeIds[0], UserHandle); if (!NT_SUCCESS(Status)) { ERR("SamOpenUser failed (Status %08lx)\n", Status); ApiStatus = NetpNtStatusToApiStatus(Status); goto done; }
done: if (RelativeIds != NULL) SamFreeMemory(RelativeIds);
if (Use != NULL) SamFreeMemory(Use);
return ApiStatus;}
/************************************************************ * NetUserAdd (NETAPI32.@) */NET_API_STATUSWINAPINetUserAdd(LPCWSTR servername, DWORD level, LPBYTE bufptr, LPDWORD parm_err){ UNICODE_STRING ServerName; UNICODE_STRING UserName; SAM_HANDLE ServerHandle = NULL; SAM_HANDLE DomainHandle = NULL; SAM_HANDLE UserHandle = NULL; ULONG GrantedAccess; ULONG RelativeId; NET_API_STATUS ApiStatus = NERR_Success; NTSTATUS Status = STATUS_SUCCESS;
TRACE("(%s, %d, %p, %p)\n", debugstr_w(servername), level, bufptr, parm_err);
if (parm_err != NULL) *parm_err = PARM_ERROR_NONE;
/* Check the info level */ switch (level) { case 1: case 2: case 3: case 4: break;
default: return ERROR_INVALID_LEVEL; }
if (servername != NULL) RtlInitUnicodeString(&ServerName, servername);
/* Connect to the SAM Server */ Status = SamConnect((servername != NULL) ? &ServerName : NULL, &ServerHandle, SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN, NULL); if (!NT_SUCCESS(Status)) { ERR("SamConnect failed (Status %08lx)\n", Status); ApiStatus = NetpNtStatusToApiStatus(Status); goto done; }
/* Open the Account Domain */ Status = OpenAccountDomain(ServerHandle, (servername != NULL) ? &ServerName : NULL, DOMAIN_CREATE_USER | DOMAIN_LOOKUP | DOMAIN_READ_PASSWORD_PARAMETERS, &DomainHandle); if (!NT_SUCCESS(Status)) { ERR("OpenAccountDomain failed (Status %08lx)\n", Status); ApiStatus = NetpNtStatusToApiStatus(Status); goto done; }
/* Initialize the user name string */ RtlInitUnicodeString(&UserName, ((PUSER_INFO_1)bufptr)->usri1_name);
/* Create the user account */ Status = SamCreateUser2InDomain(DomainHandle, &UserName, USER_NORMAL_ACCOUNT, USER_ALL_ACCESS | DELETE | WRITE_DAC, &UserHandle, &GrantedAccess, &RelativeId); if (!NT_SUCCESS(Status)) { ERR("SamCreateUser2InDomain failed (Status %08lx)\n", Status); ApiStatus = NetpNtStatusToApiStatus(Status); goto done; }
/* Set user information */ ApiStatus = SetUserInfo(UserHandle, bufptr, level, parm_err); if (ApiStatus != NERR_Success) { ERR("SetUserInfo failed (Status %lu)\n", ApiStatus); goto done; }
done: if (UserHandle != NULL) { if (ApiStatus != NERR_Success) SamDeleteUser(UserHandle); else SamCloseHandle(UserHandle); }
if (DomainHandle != NULL) SamCloseHandle(DomainHandle);
if (ServerHandle != NULL) SamCloseHandle(ServerHandle);
return ApiStatus;}
/****************************************************************************** * NetUserChangePassword (NETAPI32.@) * PARAMS * domainname [I] Optional. Domain on which the user resides or the logon * domain of the current user if NULL. * username [I] Optional. Username to change the password for or the name * of the current user if NULL. * oldpassword [I] The user's current password. * newpassword [I] The password that the user will be changed to using. * * RETURNS * Success: NERR_Success. * Failure: NERR_* failure code or win error code. * */NET_API_STATUSWINAPINetUserChangePassword(LPCWSTR domainname, LPCWSTR username, LPCWSTR oldpassword, LPCWSTR newpassword){ PMSV1_0_CHANGEPASSWORD_REQUEST RequestBuffer = NULL; PMSV1_0_CHANGEPASSWORD_RESPONSE ResponseBuffer = NULL; ULONG RequestBufferSize; ULONG ResponseBufferSize = 0; LPWSTR Ptr; ANSI_STRING PackageName; ULONG AuthenticationPackage = 0; HANDLE LsaHandle = NULL; NET_API_STATUS ApiStatus = NERR_Success; NTSTATUS Status = STATUS_SUCCESS; NTSTATUS ProtocolStatus;
TRACE("(%s, %s, ..., ...)\n", debugstr_w(domainname), debugstr_w(username));
/* FIXME: handle null domain or user name */
/* Check the parameters */ if ((oldpassword == NULL) || (newpassword == NULL)) return ERROR_INVALID_PARAMETER;
/* Connect to the LSA server */ Status = LsaConnectUntrusted(&LsaHandle); if (!NT_SUCCESS(Status)) return NetpNtStatusToApiStatus(Status);
/* Get the authentication package ID */ RtlInitAnsiString(&PackageName, MSV1_0_PACKAGE_NAME);
Status = LsaLookupAuthenticationPackage(LsaHandle, &PackageName, &AuthenticationPackage); if (!NT_SUCCESS(Status)) { ApiStatus = NetpNtStatusToApiStatus(Status); goto done; }
/* Calculate the request buffer size */ RequestBufferSize = sizeof(MSV1_0_CHANGEPASSWORD_REQUEST) + ((wcslen(domainname) + 1) * sizeof(WCHAR)) + ((wcslen(username) + 1) * sizeof(WCHAR)) + ((wcslen(oldpassword) + 1) * sizeof(WCHAR)) + ((wcslen(newpassword) + 1) * sizeof(WCHAR));
/* Allocate the request buffer */ ApiStatus = NetApiBufferAllocate(RequestBufferSize, (PVOID*)&RequestBuffer); if (ApiStatus != NERR_Success) goto done;
/* Initialize the request buffer */ RequestBuffer->MessageType = MsV1_0ChangePassword; RequestBuffer->Impersonating = TRUE;
Ptr = (LPWSTR)((ULONG_PTR)RequestBuffer + sizeof(MSV1_0_CHANGEPASSWORD_REQUEST));
/* Pack the domain name */ RequestBuffer->DomainName.Length = wcslen(domainname) * sizeof(WCHAR); RequestBuffer->DomainName.MaximumLength = RequestBuffer->DomainName.Length + sizeof(WCHAR); RequestBuffer->DomainName.Buffer = Ptr;
RtlCopyMemory(RequestBuffer->DomainName.Buffer, domainname, RequestBuffer->DomainName.MaximumLength);
Ptr = (LPWSTR)((ULONG_PTR)Ptr + RequestBuffer->DomainName.MaximumLength);
/* Pack the user name */ RequestBuffer->AccountName.Length = wcslen(username) * sizeof(WCHAR); RequestBuffer->AccountName.MaximumLength = RequestBuffer->AccountName.Length + sizeof(WCHAR); RequestBuffer->AccountName.Buffer = Ptr;
RtlCopyMemory(RequestBuffer->AccountName.Buffer, username, RequestBuffer->AccountName.MaximumLength);
Ptr = (LPWSTR)((ULONG_PTR)Ptr + RequestBuffer->AccountName.MaximumLength);
/* Pack the old password */ RequestBuffer->OldPassword.Length = wcslen(oldpassword) * sizeof(WCHAR); RequestBuffer->OldPassword.MaximumLength = RequestBuffer->OldPassword.Length + sizeof(WCHAR); RequestBuffer->OldPassword.Buffer = Ptr;
RtlCopyMemory(RequestBuffer->OldPassword.Buffer, oldpassword, RequestBuffer->OldPassword.MaximumLength);
Ptr = (LPWSTR)((ULONG_PTR)Ptr + RequestBuffer->OldPassword.MaximumLength);
/* Pack the new password */ RequestBuffer->NewPassword.Length = wcslen(newpassword) * sizeof(WCHAR); RequestBuffer->NewPassword.MaximumLength = RequestBuffer->NewPassword.Length + sizeof(WCHAR); RequestBuffer->NewPassword.Buffer = Ptr;
RtlCopyMemory(RequestBuffer->NewPassword.Buffer, newpassword, RequestBuffer->NewPassword.MaximumLength);
/* Call the authentication package */ Status = LsaCallAuthenticationPackage(LsaHandle, AuthenticationPackage, RequestBuffer, RequestBufferSize, (PVOID*)&ResponseBuffer, &ResponseBufferSize, &ProtocolStatus); if (!NT_SUCCESS(Status)) { ApiStatus = NetpNtStatusToApiStatus(Status); goto done; }
if (!NT_SUCCESS(ProtocolStatus)) { ApiStatus = NetpNtStatusToApiStatus(ProtocolStatus); goto done; }
done: if (RequestBuffer != NULL) NetApiBufferFree(RequestBuffer);
if (ResponseBuffer != NULL) LsaFreeReturnBuffer(ResponseBuffer);
if (LsaHandle != NULL) NtClose(LsaHandle);
return ApiStatus;}
/************************************************************ * NetUserDel (NETAPI32.@) */NET_API_STATUSWINAPINetUserDel(LPCWSTR servername, LPCWSTR username){ UNICODE_STRING ServerName; UNICODE_STRING UserName; SAM_HANDLE ServerHandle = NULL; SAM_HANDLE DomainHandle = NULL; SAM_HANDLE UserHandle = NULL; NET_API_STATUS ApiStatus = NERR_Success; NTSTATUS Status = STATUS_SUCCESS;
TRACE("(%s, %s)\n", debugstr_w(servername), debugstr_w(username));
if (servername != NULL) RtlInitUnicodeString(&ServerName, servername);
RtlInitUnicodeString(&UserName, username);
/* Connect to the SAM Server */ Status = SamConnect((servername != NULL) ? &ServerName : NULL, &ServerHandle, SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN, NULL); if (!NT_SUCCESS(Status)) { ERR("SamConnect failed (Status %08lx)\n", Status); ApiStatus = NetpNtStatusToApiStatus(Status); goto done; }
/* Open the Builtin Domain */ Status = OpenBuiltinDomain(ServerHandle, DOMAIN_LOOKUP, &DomainHandle); if (!NT_SUCCESS(Status)) { ERR("OpenBuiltinDomain failed (Status %08lx)\n", Status); ApiStatus = NetpNtStatusToApiStatus(Status); goto done; }
/* Open the user account in the builtin domain */ ApiStatus = OpenUserByName(DomainHandle, &UserName, DELETE, &UserHandle); if (ApiStatus != NERR_Success && ApiStatus != ERROR_NONE_MAPPED) { TRACE("OpenUserByName(%wZ) failed (ApiStatus %lu)\n", &UserName, ApiStatus); goto done; }
if (UserHandle == NULL) { if (DomainHandle != NULL) { SamCloseHandle(DomainHandle); DomainHandle = NULL; }
/* Open the Acount Domain */ Status = OpenAccountDomain(ServerHandle, (servername != NULL) ? &ServerName : NULL, DOMAIN_LOOKUP, &DomainHandle); if (!NT_SUCCESS(Status)) { ERR("OpenAccountDomain failed (Status %08lx)\n", Status); ApiStatus = NetpNtStatusToApiStatus(Status); goto done; }
/* Open the user account in the account domain */ ApiStatus = OpenUserByName(DomainHandle, &UserName, DELETE, &UserHandle); if (ApiStatus != NERR_Success) { ERR("OpenUserByName(%wZ) failed (ApiStatus %lu)\n", &UserName, ApiStatus); if (ApiStatus == ERROR_NONE_MAPPED) ApiStatus = NERR_UserNotFound; goto done; } }
/* Delete the user */ Status = SamDeleteUser(UserHandle); if (!NT_SUCCESS(Status)) { ERR("SamDeleteUser failed (Status %08lx)\n", Status); ApiStatus = NetpNtStatusToApiStatus(Status); goto done; }
/* A successful delete invalidates the handle */ UserHandle = NULL;
done: if (UserHandle != NULL) SamCloseHandle(UserHandle);
if (DomainHandle != NULL) SamCloseHandle(DomainHandle);
if (ServerHandle != NULL) SamCloseHandle(ServerHandle);
return ApiStatus;}
staticNET_API_STATUSAllocateEnumContext( PENUM_CONTEXT *AllocatedEnumContext){ NET_API_STATUS ApiStatus; PENUM_CONTEXT EnumContext;
/* Allocate the context structure */ ApiStatus = NetApiBufferAllocate(sizeof(ENUM_CONTEXT), (PVOID*)&EnumContext); if (ApiStatus != NERR_Success) return ApiStatus;
/* Initialize the fields */ EnumContext->EnumerationContext = 0; EnumContext->Buffer = NULL; EnumContext->Count = 0; EnumContext->Index = 0; EnumContext->BuiltinDone = FALSE;
/* Set a "unique" handle */ EnumContext->EnumHandle = InterlockedIncrement(&g_EnumContextHandle); if (EnumContext->EnumHandle == 0) { EnumContext->EnumHandle = InterlockedIncrement(&g_EnumContextHandle); }
/* Insert the context in the list */ EnterCriticalSection(&g_EnumContextListLock); InsertTailList(&g_EnumContextListHead, &EnumContext->ListLink); LeaveCriticalSection(&g_EnumContextListLock);
*AllocatedEnumContext = EnumContext; return NERR_Success;}
staticVOIDFreeEnumContext( PENUM_CONTEXT EnumContext)
{ /* Remove the context from the list */ EnterCriticalSection(&g_EnumContextListLock); RemoveEntryList(&EnumContext->ListLink); LeaveCriticalSection(&g_EnumContextListLock);
/* Free it */ NetApiBufferFree(EnumContext);}
staticPENUM_CONTEXTLookupEnumContext( SAM_ENUMERATE_HANDLE EnumerationHandle){ PENUM_CONTEXT FoundEnumContext = NULL; PLIST_ENTRY ListEntry;
/* Acquire the list lock */ EnterCriticalSection(&g_EnumContextListLock);
/* Search the list for the handle */ for (ListEntry = g_EnumContextListHead.Flink; ListEntry != &g_EnumContextListHead; ListEntry = ListEntry->Flink) { PENUM_CONTEXT EnumContext = CONTAINING_RECORD(ListEntry, ENUM_CONTEXT, ListLink); if (EnumContext->EnumHandle == EnumerationHandle) { FoundEnumContext = EnumContext; break; } }
/* Release the list lock */ LeaveCriticalSection(&g_EnumContextListLock);
return FoundEnumContext;}
/************************************************************ * NetUserEnum (NETAPI32.@) */NET_API_STATUSWINAPINetUserEnum(LPCWSTR servername, DWORD level, DWORD filter, LPBYTE* bufptr, DWORD prefmaxlen, LPDWORD entriesread, LPDWORD totalentries, LPDWORD resume_handle){ UNICODE_STRING ServerName; PSAM_RID_ENUMERATION CurrentUser; PENUM_CONTEXT EnumContext = NULL; LPVOID Buffer = NULL; ULONG i; SAM_HANDLE UserHandle = NULL; ACCESS_MASK DesiredAccess; NET_API_STATUS ApiStatus = NERR_Success; NTSTATUS Status = STATUS_SUCCESS;
TRACE("(%s %d 0x%d %p %d %p %p %p)\n", debugstr_w(servername), level, filter, bufptr, prefmaxlen, entriesread, totalentries, resume_handle);
*entriesread = 0; *totalentries = 0; *bufptr = NULL;
if (servername != NULL) RtlInitUnicodeString(&ServerName, servername);
if (resume_handle != NULL && *resume_handle != 0) { EnumContext = LookupEnumContext(*resume_handle); } else { ApiStatus = AllocateEnumContext(&EnumContext); if (ApiStatus != NERR_Success) goto done;
Status = SamConnect((servername != NULL) ? &ServerName : NULL, &EnumContext->ServerHandle, SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN, NULL); if (!NT_SUCCESS(Status)) { ERR("SamConnect failed (Status %08lx)\n", Status); ApiStatus = NetpNtStatusToApiStatus(Status); goto done; }
/* Get the Account Domain SID */ Status = GetAccountDomainSid((servername != NULL) ? &ServerName : NULL, &EnumContext->AccountDomainSid); if (!NT_SUCCESS(Status)) { ERR("GetAccountDomainSid failed (Status %08lx)\n", Status); ApiStatus = NetpNtStatusToApiStatus(Status); goto done; }
/* Open the Account Domain */ Status = SamOpenDomain(EnumContext->ServerHandle, DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP, EnumContext->AccountDomainSid, &EnumContext->AccountDomainHandle); if (!NT_SUCCESS(Status)) { ERR("SamOpenDomain failed (Status %08lx)\n", Status); ApiStatus = NetpNtStatusToApiStatus(Status); goto done; }
/* Get the Builtin Domain SID */ Status = GetBuiltinDomainSid(&EnumContext->BuiltinDomainSid); if (!NT_SUCCESS(Status)) { ERR("GetBuiltinDomainSid failed (Status %08lx)\n", Status); ApiStatus = NetpNtStatusToApiStatus(Status); goto done; }
DesiredAccess = DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP; if ((level == 1) || (level == 2) || (level == 3) || (level == 4) || (level == 11)) DesiredAccess |= DOMAIN_GET_ALIAS_MEMBERSHIP;
/* Open the Builtin Domain */ Status = SamOpenDomain(EnumContext->ServerHandle, DesiredAccess, EnumContext->BuiltinDomainSid, &EnumContext->BuiltinDomainHandle); if (!NT_SUCCESS(Status)) { ERR("SamOpenDomain failed (Status %08lx)\n", Status); ApiStatus = NetpNtStatusToApiStatus(Status); goto done; } }
// while (TRUE)// { TRACE("EnumContext->Index: %lu\n", EnumContext->Index); TRACE("EnumContext->Count: %lu\n", EnumContext->Count);
if (EnumContext->Index >= EnumContext->Count) {// if (EnumContext->BuiltinDone != FALSE)// {// ApiStatus = NERR_Success;// goto done;// }
TRACE("Calling SamEnumerateUsersInDomain\n"); Status = SamEnumerateUsersInDomain(EnumContext->AccountDomainHandle, //BuiltinDomainHandle, &EnumContext->EnumerationContext, 0, (PVOID *)&EnumContext->Buffer, prefmaxlen, &EnumContext->Count);
TRACE("SamEnumerateUsersInDomain returned (Status %08lx)\n", Status); if (!NT_SUCCESS(Status)) { ERR("SamEnumerateUsersInDomain failed (Status %08lx)\n", Status); ApiStatus = NetpNtStatusToApiStatus(Status); goto done; }
if (Status == STATUS_MORE_ENTRIES) { ApiStatus = NERR_BufTooSmall; goto done; } else { EnumContext->BuiltinDone = TRUE; } }
TRACE("EnumContext: %lu\n", EnumContext); TRACE("EnumContext->Count: %lu\n", EnumContext->Count); TRACE("EnumContext->Buffer: %p\n", EnumContext->Buffer);
/* Get a pointer to the current user */ CurrentUser = &EnumContext->Buffer[EnumContext->Index];
TRACE("RID: %lu\n", CurrentUser->RelativeId);
DesiredAccess = READ_CONTROL | USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT; if ((level == 1) || (level == 2) || (level == 3) || (level == 4) || (level == 11)) DesiredAccess |= USER_LIST_GROUPS;
Status = SamOpenUser(EnumContext->AccountDomainHandle, //BuiltinDomainHandle, DesiredAccess, CurrentUser->RelativeId, &UserHandle); if (!NT_SUCCESS(Status)) { ERR("SamOpenUser failed (Status %08lx)\n", Status); ApiStatus = NetpNtStatusToApiStatus(Status); goto done; }
ApiStatus = BuildUserInfoBuffer(EnumContext->BuiltinDomainHandle, UserHandle, EnumContext->AccountDomainSid, CurrentUser->RelativeId, level, &Buffer); if (ApiStatus != NERR_Success) { ERR("BuildUserInfoBuffer failed (ApiStatus %lu)\n", ApiStatus); goto done; }
SamCloseHandle(UserHandle); UserHandle = NULL;
EnumContext->Index++;
(*entriesread)++;// }
done: if (ApiStatus == NERR_Success && EnumContext != NULL && EnumContext->Index < EnumContext->Count) ApiStatus = ERROR_MORE_DATA;
if (EnumContext != NULL) *totalentries = EnumContext->Count;
if (resume_handle == NULL || ApiStatus != ERROR_MORE_DATA) { if (EnumContext != NULL) { if (EnumContext->BuiltinDomainHandle != NULL) SamCloseHandle(EnumContext->BuiltinDomainHandle);
if (EnumContext->AccountDomainHandle != NULL) SamCloseHandle(EnumContext->AccountDomainHandle);
if (EnumContext->BuiltinDomainSid != NULL) RtlFreeHeap(RtlGetProcessHeap(), 0, EnumContext->BuiltinDomainSid);
if (EnumContext->AccountDomainSid != NULL) RtlFreeHeap(RtlGetProcessHeap(), 0, EnumContext->AccountDomainSid);
if (EnumContext->ServerHandle != NULL) SamCloseHandle(EnumContext->ServerHandle);
if (EnumContext->Buffer != NULL) { for (i = 0; i < EnumContext->Count; i++) { SamFreeMemory(EnumContext->Buffer[i].Name.Buffer); }
SamFreeMemory(EnumContext->Buffer); }
FreeEnumContext(EnumContext); EnumContext = NULL; } }
if (UserHandle != NULL) SamCloseHandle(UserHandle);
if (resume_handle != NULL) *resume_handle = EnumContext ? EnumContext->EnumHandle : 0;
*bufptr = (LPBYTE)Buffer;
TRACE("return %lu\n", ApiStatus);
return ApiStatus;}
/************************************************************ * NetUserGetGroups (NETAPI32.@) */NET_API_STATUSWINAPINetUserGetGroups(LPCWSTR servername, LPCWSTR username, DWORD level, LPBYTE *bufptr, DWORD prefixmaxlen, LPDWORD entriesread, LPDWORD totalentries){ UNICODE_STRING ServerName; UNICODE_STRING UserName; SAM_HANDLE ServerHandle = NULL; SAM_HANDLE AccountDomainHandle = NULL; SAM_HANDLE UserHandle = NULL; PSID AccountDomainSid = NULL; PULONG RelativeIds = NULL; PSID_NAME_USE Use = NULL; PGROUP_MEMBERSHIP GroupMembership = NULL; ULONG GroupCount;
NET_API_STATUS ApiStatus = NERR_Success; NTSTATUS Status = STATUS_SUCCESS;
TRACE("%s %s %d %p %d %p %p stub\n", debugstr_w(servername), debugstr_w(username), level, bufptr, prefixmaxlen, entriesread, totalentries);
if (servername != NULL) RtlInitUnicodeString(&ServerName, servername);
RtlInitUnicodeString(&UserName, username);
/* Connect to the SAM Server */ Status = SamConnect((servername != NULL) ? &ServerName : NULL, &ServerHandle, SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN, NULL); if (!NT_SUCCESS(Status)) { ERR("SamConnect failed (Status %08lx)\n", Status); ApiStatus = NetpNtStatusToApiStatus(Status); goto done; }
/* Get the Account Domain SID */ Status = GetAccountDomainSid((servername != NULL) ? &ServerName : NULL, &AccountDomainSid); if (!NT_SUCCESS(Status)) { ERR("GetAccountDomainSid failed (Status %08lx)\n", Status); ApiStatus = NetpNtStatusToApiStatus(Status); goto done; }
/* Open the Account Domain */ Status = SamOpenDomain(ServerHandle, DOMAIN_LOOKUP | DOMAIN_GET_ALIAS_MEMBERSHIP, AccountDomainSid, &AccountDomainHandle); if (!NT_SUCCESS(Status)) { ERR("SamOpenDomain failed (Status %08lx)\n", Status); ApiStatus = NetpNtStatusToApiStatus(Status); goto done; }
/* Get the RID for the given user name */ Status = SamLookupNamesInDomain(AccountDomainHandle, 1, &UserName, &RelativeIds, &Use); if (!NT_SUCCESS(Status)) { ERR("SamLookupNamesInDomain(%wZ) failed (Status %08lx)\n", &UserName, Status); if (Status == STATUS_NONE_MAPPED) ApiStatus = NERR_UserNotFound; else ApiStatus = NetpNtStatusToApiStatus(Status); goto done; }
/* Fail, if it is not a user account */ if (Use[0] != SidTypeUser) { ERR("Account is not a User!\n"); ApiStatus = NERR_UserNotFound; goto done; }
/* Open the user object */ Status = SamOpenUser(AccountDomainHandle, USER_LIST_GROUPS, RelativeIds[0], &UserHandle); if (!NT_SUCCESS(Status)) { ERR("SamOpenUser failed (Status %08lx)\n", Status); ApiStatus = NetpNtStatusToApiStatus(Status); goto done; }
/* Get the group memberships of this user */ Status = SamGetGroupsForUser(UserHandle, &GroupMembership, &GroupCount); if (!NT_SUCCESS(Status)) { ERR("SamGetGroupsForUser failed (Status %08lx)\n", Status); ApiStatus = NetpNtStatusToApiStatus(Status); goto done; }
/* If there is no group membership, we're done */ if (GroupCount == 0) { ApiStatus = NERR_Success; goto done; }
done:
if (GroupMembership != NULL) SamFreeMemory(GroupMembership);
if (UserHandle != NULL) SamCloseHandle(UserHandle);
if (RelativeIds != NULL) SamFreeMemory(RelativeIds);
if (Use != NULL) SamFreeMemory(Use);
if (AccountDomainSid != NULL) RtlFreeHeap(RtlGetProcessHeap(), 0, AccountDomainSid);
if (AccountDomainHandle != NULL) SamCloseHandle(AccountDomainHandle);
if (ServerHandle != NULL) SamCloseHandle(ServerHandle);
if (ApiStatus != NERR_Success && ApiStatus != ERROR_MORE_DATA) { *entriesread = 0; *totalentries = 0; } else {// *entriesread = Count;// *totalentries = Count; }
// *bufptr = (LPBYTE)Buffer;
return ApiStatus;}
/************************************************************ * NetUserGetInfo (NETAPI32.@) */NET_API_STATUSWINAPINetUserGetInfo(LPCWSTR servername, LPCWSTR username, DWORD level, LPBYTE* bufptr){ UNICODE_STRING ServerName; UNICODE_STRING UserName; SAM_HANDLE ServerHandle = NULL; SAM_HANDLE AccountDomainHandle = NULL; SAM_HANDLE BuiltinDomainHandle = NULL; SAM_HANDLE UserHandle = NULL; PULONG RelativeIds = NULL; PSID_NAME_USE Use = NULL; LPVOID Buffer = NULL; PSID AccountDomainSid = NULL; PSID BuiltinDomainSid = NULL; ACCESS_MASK DesiredAccess; NET_API_STATUS ApiStatus = NERR_Success; NTSTATUS Status = STATUS_SUCCESS;
TRACE("(%s, %s, %d, %p)\n", debugstr_w(servername), debugstr_w(username), level, bufptr);
if (servername != NULL) RtlInitUnicodeString(&ServerName, servername);
RtlInitUnicodeString(&UserName, username);
/* Connect to the SAM Server */ Status = SamConnect((servername != NULL) ? &ServerName : NULL, &ServerHandle, SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN, NULL); if (!NT_SUCCESS(Status)) { ERR("SamConnect failed (Status %08lx)\n", Status); ApiStatus = NetpNtStatusToApiStatus(Status); goto done; }
/* Get the Builtin Domain SID */ Status = GetBuiltinDomainSid(&BuiltinDomainSid); if (!NT_SUCCESS(Status)) { ERR("GetBuiltinDomainSid failed (Status %08lx)\n", Status); ApiStatus = NetpNtStatusToApiStatus(Status); goto done; }
DesiredAccess = DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP; if ((level == 1) || (level == 2) || (level == 3) || (level == 4) || (level == 11)) DesiredAccess |= DOMAIN_GET_ALIAS_MEMBERSHIP;
/* Open the Builtin Domain */ Status = SamOpenDomain(ServerHandle, DesiredAccess, BuiltinDomainSid, &BuiltinDomainHandle); if (!NT_SUCCESS(Status)) { ERR("SamOpenDomain failed (Status %08lx)\n", Status); ApiStatus = NetpNtStatusToApiStatus(Status); goto done; }
/* Get the Account Domain SID */ Status = GetAccountDomainSid((servername != NULL) ? &ServerName : NULL, &AccountDomainSid); if (!NT_SUCCESS(Status)) { ERR("GetAccountDomainSid failed (Status %08lx)\n", Status); ApiStatus = NetpNtStatusToApiStatus(Status); goto done; }
/* Open the Account Domain */ Status = SamOpenDomain(ServerHandle, DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP, AccountDomainSid, &AccountDomainHandle); if (!NT_SUCCESS(Status)) { ERR("SamOpenDomain failed (Status %08lx)\n", Status); ApiStatus = NetpNtStatusToApiStatus(Status); goto done; }
/* Get the RID for the given user name */ Status = SamLookupNamesInDomain(AccountDomainHandle, 1, &UserName, &RelativeIds, &Use); if (!NT_SUCCESS(Status)) { ERR("SamLookupNamesInDomain(%wZ) failed (Status %08lx)\n", &UserName, Status); if (Status == STATUS_NONE_MAPPED) ApiStatus = NERR_UserNotFound; else ApiStatus = NetpNtStatusToApiStatus(Status); goto done; }
/* Check if the account is a user account */ if (Use[0] != SidTypeUser) { ERR("No user found!\n"); ApiStatus = NERR_UserNotFound; goto done; }
TRACE("RID: %lu\n", RelativeIds[0]);
DesiredAccess = READ_CONTROL | USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT; if ((level == 1) || (level == 2) || (level == 3) || (level == 4) || (level == 11)) DesiredAccess |= USER_LIST_GROUPS;
/* Open the user object */ Status = SamOpenUser(AccountDomainHandle, DesiredAccess, RelativeIds[0], &UserHandle); if (!NT_SUCCESS(Status)) { ERR("SamOpenUser failed (Status %08lx)\n", Status); ApiStatus = NetpNtStatusToApiStatus(Status); goto done; }
ApiStatus = BuildUserInfoBuffer(BuiltinDomainHandle, UserHandle, AccountDomainSid, RelativeIds[0], level, &Buffer); if (ApiStatus != NERR_Success) { ERR("BuildUserInfoBuffer failed (ApiStatus %08lu)\n", ApiStatus); goto done; }
done: if (UserHandle != NULL) SamCloseHandle(UserHandle);
if (RelativeIds != NULL) SamFreeMemory(RelativeIds);
if (Use != NULL) SamFreeMemory(Use);
if (AccountDomainHandle != NULL) SamCloseHandle(AccountDomainHandle);
if (AccountDomainSid != NULL) RtlFreeHeap(RtlGetProcessHeap(), 0, AccountDomainSid);
if (BuiltinDomainHandle != NULL) SamCloseHandle(BuiltinDomainHandle);
if (BuiltinDomainSid != NULL) RtlFreeHeap(RtlGetProcessHeap(), 0, BuiltinDomainSid);
if (ServerHandle != NULL) SamCloseHandle(ServerHandle);
*bufptr = (LPBYTE)Buffer;
return ApiStatus;}
/************************************************************ * NetUserGetLocalGroups (NETAPI32.@) */NET_API_STATUSWINAPINetUserGetLocalGroups(LPCWSTR servername, LPCWSTR username, DWORD level, DWORD flags, LPBYTE* bufptr, DWORD prefmaxlen, LPDWORD entriesread, LPDWORD totalentries){ UNICODE_STRING ServerName; UNICODE_STRING UserName; SAM_HANDLE ServerHandle = NULL; SAM_HANDLE BuiltinDomainHandle = NULL; SAM_HANDLE AccountDomainHandle = NULL; PSID AccountDomainSid = NULL; PSID UserSid = NULL; PULONG RelativeIds = NULL; PSID_NAME_USE Use = NULL; ULONG BuiltinMemberCount = 0; ULONG AccountMemberCount = 0; PULONG BuiltinAliases = NULL; PULONG AccountAliases = NULL; PUNICODE_STRING BuiltinNames = NULL; PUNICODE_STRING AccountNames = NULL; PLOCALGROUP_USERS_INFO_0 Buffer = NULL; ULONG Size; ULONG Count = 0; ULONG Index; ULONG i; LPWSTR StrPtr; NET_API_STATUS ApiStatus = NERR_Success; NTSTATUS Status = STATUS_SUCCESS;
TRACE("(%s, %s, %d, %08x, %p %d, %p, %p) stub!\n", debugstr_w(servername), debugstr_w(username), level, flags, bufptr, prefmaxlen, entriesread, totalentries);
if (level != 0) return ERROR_INVALID_LEVEL;
if (flags & ~LG_INCLUDE_INDIRECT) return ERROR_INVALID_PARAMETER;
if (flags & LG_INCLUDE_INDIRECT) { WARN("The flag LG_INCLUDE_INDIRECT is not supported yet!\n"); }
if (servername != NULL) RtlInitUnicodeString(&ServerName, servername);
RtlInitUnicodeString(&UserName, username);
/* Connect to the SAM Server */ Status = SamConnect((servername != NULL) ? &ServerName : NULL, &ServerHandle, SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN, NULL); if (!NT_SUCCESS(Status)) { ERR("SamConnect failed (Status %08lx)\n", Status); ApiStatus = NetpNtStatusToApiStatus(Status); goto done; }
/* Open the Builtin Domain */ Status = OpenBuiltinDomain(ServerHandle, DOMAIN_LOOKUP | DOMAIN_GET_ALIAS_MEMBERSHIP, &BuiltinDomainHandle); if (!NT_SUCCESS(Status)) { ERR("OpenBuiltinDomain failed (Status %08lx)\n", Status); ApiStatus = NetpNtStatusToApiStatus(Status); goto done; }
/* Get the Account Domain SID */ Status = GetAccountDomainSid((servername != NULL) ? &ServerName : NULL, &AccountDomainSid); if (!NT_SUCCESS(Status)) { ERR("GetAccountDomainSid failed (Status %08lx)\n", Status); ApiStatus = NetpNtStatusToApiStatus(Status); goto done; }
/* Open the Account Domain */ Status = SamOpenDomain(ServerHandle, DOMAIN_LOOKUP | DOMAIN_GET_ALIAS_MEMBERSHIP, AccountDomainSid, &AccountDomainHandle); if (!NT_SUCCESS(Status)) { ERR("SamOpenDomain failed (Status %08lx)\n", Status); ApiStatus = NetpNtStatusToApiStatus(Status); goto done; }
/* Get the RID for the given user name */ Status = SamLookupNamesInDomain(AccountDomainHandle, 1, &UserName, &RelativeIds, &Use); if (!NT_SUCCESS(Status)) { ERR("SamLookupNamesInDomain(%wZ) failed (Status %08lx)\n", &UserName, Status); if (Status == STATUS_NONE_MAPPED) ApiStatus = NERR_UserNotFound; else ApiStatus = NetpNtStatusToApiStatus(Status); goto done; }
/* Fail, if it is not a user account */ if (Use[0] != SidTypeUser) { ERR("Account is not a User!\n"); ApiStatus = NERR_UserNotFound; goto done; }
/* Build the User SID from the Account Domain SID and the users RID */ ApiStatus = BuildSidFromSidAndRid(AccountDomainSid, RelativeIds[0], &UserSid); if (ApiStatus != NERR_Success) { ERR("BuildSidFromSidAndRid failed!\n"); goto done; }
/* Get alias memberships in the Builtin Domain */ Status = SamGetAliasMembership(BuiltinDomainHandle, 1, &UserSid, &BuiltinMemberCount, &BuiltinAliases); if (!NT_SUCCESS(Status)) { ERR("SamGetAliasMembership failed (Status %08lx)\n", Status); ApiStatus = NetpNtStatusToApiStatus(Status); goto done; }
if (BuiltinMemberCount > 0) { /* Get the Names of the builtin alias members */ Status = SamLookupIdsInDomain(BuiltinDomainHandle, BuiltinMemberCount, BuiltinAliases, &BuiltinNames, NULL); if (!NT_SUCCESS(Status)) { ERR("SamLookupIdsInDomain failed (Status %08lx)\n", Status); ApiStatus = NetpNtStatusToApiStatus(Status); goto done; } }
/* Get alias memberships in the Account Domain */ Status = SamGetAliasMembership(AccountDomainHandle, 1, &UserSid, &AccountMemberCount, &AccountAliases); if (!NT_SUCCESS(Status)) { ERR("SamGetAliasMembership failed (Status %08lx)\n", Status); ApiStatus = NetpNtStatusToApiStatus(Status); goto done; }
if (AccountMemberCount > 0) { /* Get the Names of the builtin alias members */ Status = SamLookupIdsInDomain(AccountDomainHandle, AccountMemberCount, AccountAliases, &AccountNames, NULL); if (!NT_SUCCESS(Status)) { ERR("SamLookupIdsInDomain failed (Status %08lx)\n", Status); ApiStatus = NetpNtStatusToApiStatus(Status); goto done; } }
/* Calculate the required buffer size */ Size = 0;
for (i = 0; i < BuiltinMemberCount; i++) { if (BuiltinNames[i].Length > 0) { Size += (sizeof(LOCALGROUP_USERS_INFO_0) + BuiltinNames[i].Length + sizeof(UNICODE_NULL)); Count++; } }
for (i = 0; i < AccountMemberCount; i++) { if (AccountNames[i].Length > 0) { Size += (sizeof(LOCALGROUP_USERS_INFO_0) + AccountNames[i].Length + sizeof(UNICODE_NULL)); Count++; } }
if (Size == 0) { ApiStatus = NERR_Success; goto done; }
/* Allocate buffer */ ApiStatus = NetApiBufferAllocate(Size, (LPVOID*)&Buffer); if (ApiStatus != NERR_Success) goto done;
ZeroMemory(Buffer, Size);
StrPtr = (LPWSTR)((INT_PTR)Buffer + Count * sizeof(LOCALGROUP_USERS_INFO_0));
/* Copy data to the allocated buffer */ Index = 0; for (i = 0; i < BuiltinMemberCount; i++) { if (BuiltinNames[i].Length > 0) { CopyMemory(StrPtr, BuiltinNames[i].Buffer, BuiltinNames[i].Length); Buffer[Index].lgrui0_name = StrPtr;
StrPtr = (LPWSTR)((INT_PTR)StrPtr + BuiltinNames[i].Length + sizeof(UNICODE_NULL)); Index++; } }
for (i = 0; i < AccountMemberCount; i++) { if (AccountNames[i].Length > 0) { CopyMemory(StrPtr, AccountNames[i].Buffer, AccountNames[i].Length); Buffer[Index].lgrui0_name = StrPtr;
StrPtr = (LPWSTR)((INT_PTR)StrPtr + AccountNames[i].Length + sizeof(UNICODE_NULL)); Index++; } }
done: if (AccountNames != NULL) SamFreeMemory(AccountNames);
if (BuiltinNames != NULL) SamFreeMemory(BuiltinNames);
if (AccountAliases != NULL) SamFreeMemory(AccountAliases);
if (BuiltinAliases != NULL) SamFreeMemory(BuiltinAliases);
if (RelativeIds != NULL) SamFreeMemory(RelativeIds);
if (Use != NULL) SamFreeMemory(Use);
if (UserSid != NULL) NetApiBufferFree(UserSid);
if (AccountDomainSid != NULL) RtlFreeHeap(RtlGetProcessHeap(), 0, AccountDomainSid);
if (AccountDomainHandle != NULL) SamCloseHandle(AccountDomainHandle);
if (BuiltinDomainHandle != NULL) SamCloseHandle(BuiltinDomainHandle);
if (ServerHandle != NULL) SamCloseHandle(ServerHandle);
if (ApiStatus != NERR_Success && ApiStatus != ERROR_MORE_DATA) { *entriesread = 0; *totalentries = 0; } else { *entriesread = Count; *totalentries = Count; }
*bufptr = (LPBYTE)Buffer;
return ApiStatus;}
/****************************************************************************** * NetUserModalsGet (NETAPI32.@) * * Retrieves global information for all users and global groups in the security * database. * * PARAMS * servername [I] Specifies the DNS or the NetBIOS name of the remote server * on which the function is to execute. * level [I] Information level of the data. * 0 Return global passwords parameters. bufptr points to a * USER_MODALS_INFO_0 struct. * 1 Return logon server and domain controller information. bufptr * points to a USER_MODALS_INFO_1 struct. * 2 Return domain name and identifier. bufptr points to a * USER_MODALS_INFO_2 struct. * 3 Return lockout information. bufptr points to a USER_MODALS_INFO_3 * struct. * bufptr [O] Buffer that receives the data. * * RETURNS * Success: NERR_Success. * Failure: * ERROR_ACCESS_DENIED - the user does not have access to the info. * NERR_InvalidComputer - computer name is invalid. */NET_API_STATUSWINAPINetUserModalsGet(LPCWSTR servername, DWORD level, LPBYTE *bufptr){ UNICODE_STRING ServerName; SAM_HANDLE ServerHandle = NULL; SAM_HANDLE DomainHandle = NULL; PSID DomainSid = NULL; PDOMAIN_PASSWORD_INFORMATION PasswordInfo = NULL; PDOMAIN_LOGOFF_INFORMATION LogoffInfo = NULL; PDOMAIN_SERVER_ROLE_INFORMATION ServerRoleInfo = NULL; PDOMAIN_REPLICATION_INFORMATION ReplicationInfo = NULL; PDOMAIN_NAME_INFORMATION NameInfo = NULL; PDOMAIN_LOCKOUT_INFORMATION LockoutInfo = NULL; ULONG DesiredAccess; ULONG BufferSize; PUSER_MODALS_INFO_0 umi0; PUSER_MODALS_INFO_1 umi1; PUSER_MODALS_INFO_2 umi2; PUSER_MODALS_INFO_3 umi3; NET_API_STATUS ApiStatus = NERR_Success; NTSTATUS Status = STATUS_SUCCESS;
TRACE("(%s %d %p)\n", debugstr_w(servername), level, bufptr);
*bufptr = NULL;
if (servername != NULL) RtlInitUnicodeString(&ServerName, servername);
/* Connect to the SAM Server */ Status = SamConnect((servername != NULL) ? &ServerName : NULL, &ServerHandle, SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN, NULL); if (!NT_SUCCESS(Status)) { ERR("SamConnect failed (Status %08lx)\n", Status); ApiStatus = NetpNtStatusToApiStatus(Status); goto done; }
/* Get the Account Domain SID */ Status = GetAccountDomainSid((servername != NULL) ? &ServerName : NULL, &DomainSid); if (!NT_SUCCESS(Status)) { ERR("GetAccountDomainSid failed (Status %08lx)\n", Status); ApiStatus = NetpNtStatusToApiStatus(Status); goto done; }
switch (level) { case 0: DesiredAccess = DOMAIN_READ_OTHER_PARAMETERS | DOMAIN_READ_PASSWORD_PARAMETERS; break;
case 1: DesiredAccess = DOMAIN_READ_OTHER_PARAMETERS; break;
case 2: DesiredAccess = DOMAIN_READ_OTHER_PARAMETERS; break;
case 3: DesiredAccess = DOMAIN_READ_PASSWORD_PARAMETERS; break;
default: ApiStatus = ERROR_INVALID_LEVEL; goto done; }
/* Open the Account Domain */ Status = SamOpenDomain(ServerHandle, DesiredAccess, DomainSid, &DomainHandle); if (!NT_SUCCESS(Status)) { ERR("OpenAccountDomain failed (Status %08lx)\n", Status); ApiStatus = NetpNtStatusToApiStatus(Status); goto done; }
switch (level) { case 0: /* return global passwords parameters */ Status = SamQueryInformationDomain(DomainHandle, DomainPasswordInformation, (PVOID*)&PasswordInfo); if (!NT_SUCCESS(Status)) { ApiStatus = NetpNtStatusToApiStatus(Status); goto done; }
Status = SamQueryInformationDomain(DomainHandle, DomainLogoffInformation, (PVOID*)&LogoffInfo); if (!NT_SUCCESS(Status)) { ApiStatus = NetpNtStatusToApiStatus(Status); goto done; }
BufferSize = sizeof(USER_MODALS_INFO_0); break;
case 1: /* return logon server and domain controller info */ Status = SamQueryInformationDomain(DomainHandle, DomainServerRoleInformation, (PVOID*)&ServerRoleInfo); if (!NT_SUCCESS(Status)) { ApiStatus = NetpNtStatusToApiStatus(Status); goto done; }
Status = SamQueryInformationDomain(DomainHandle, DomainReplicationInformation, (PVOID*)&ReplicationInfo); if (!NT_SUCCESS(Status)) { ApiStatus = NetpNtStatusToApiStatus(Status); goto done; }
BufferSize = sizeof(USER_MODALS_INFO_1) + ReplicationInfo->ReplicaSourceNodeName.Length + sizeof(WCHAR); break;
case 2: /* return domain name and identifier */ Status = SamQueryInformationDomain(DomainHandle, DomainNameInformation, (PVOID*)&NameInfo); if (!NT_SUCCESS(Status)) { ApiStatus = NetpNtStatusToApiStatus(Status); goto done; }
BufferSize = sizeof( USER_MODALS_INFO_2 ) + NameInfo->DomainName.Length + sizeof(WCHAR) + RtlLengthSid(DomainSid); break;
case 3: /* return lockout information */ Status = SamQueryInformationDomain(DomainHandle, DomainLockoutInformation, (PVOID*)&LockoutInfo); if (!NT_SUCCESS(Status)) { ApiStatus = NetpNtStatusToApiStatus(Status); goto done; }
BufferSize = sizeof(USER_MODALS_INFO_3); break;
default: TRACE("Invalid level %d is specified\n", level); ApiStatus = ERROR_INVALID_LEVEL; goto done; }
ApiStatus = NetApiBufferAllocate(BufferSize, (LPVOID *)bufptr); if (ApiStatus != NERR_Success) { WARN("NetApiBufferAllocate() failed\n"); goto done; }
switch (level) { case 0: umi0 = (PUSER_MODALS_INFO_0)*bufptr;
umi0->usrmod0_min_passwd_len = PasswordInfo->MinPasswordLength; umi0->usrmod0_max_passwd_age = (ULONG)(-PasswordInfo->MaxPasswordAge.QuadPart / 10000000); umi0->usrmod0_min_passwd_age = DeltaTimeToSeconds(PasswordInfo->MinPasswordAge); umi0->usrmod0_force_logoff = DeltaTimeToSeconds(LogoffInfo->ForceLogoff); umi0->usrmod0_password_hist_len = PasswordInfo->PasswordHistoryLength; break;
case 1: umi1 = (PUSER_MODALS_INFO_1)*bufptr;
switch (ServerRoleInfo->DomainServerRole) { case DomainServerRolePrimary: umi1->usrmod1_role = UAS_ROLE_PRIMARY; break;
case DomainServerRoleBackup: umi1->usrmod1_role = UAS_ROLE_BACKUP; break;
default: ApiStatus = NERR_InternalError; goto done; }
umi1->usrmod1_primary = (LPWSTR)(*bufptr + sizeof(USER_MODALS_INFO_1)); RtlCopyMemory(umi1->usrmod1_primary, ReplicationInfo->ReplicaSourceNodeName.Buffer, ReplicationInfo->ReplicaSourceNodeName.Length); umi1->usrmod1_primary[ReplicationInfo->ReplicaSourceNodeName.Length / sizeof(WCHAR)] = UNICODE_NULL; break;
case 2: umi2 = (PUSER_MODALS_INFO_2)*bufptr;
umi2->usrmod2_domain_name = (LPWSTR)(*bufptr + sizeof(USER_MODALS_INFO_2)); RtlCopyMemory(umi2->usrmod2_domain_name, NameInfo->DomainName.Buffer, NameInfo->DomainName.Length); umi2->usrmod2_domain_name[NameInfo->DomainName.Length / sizeof(WCHAR)] = UNICODE_NULL;
umi2->usrmod2_domain_id = *bufptr + sizeof(USER_MODALS_INFO_2) + NameInfo->DomainName.Length + sizeof(WCHAR); RtlCopyMemory(umi2->usrmod2_domain_id, DomainSid, RtlLengthSid(DomainSid)); break;
case 3: umi3 = (PUSER_MODALS_INFO_3)*bufptr; umi3->usrmod3_lockout_duration = DeltaTimeToSeconds(LockoutInfo->LockoutDuration); umi3->usrmod3_lockout_observation_window = DeltaTimeToSeconds(LockoutInfo->LockoutObservationWindow ); umi3->usrmod3_lockout_threshold = LockoutInfo->LockoutThreshold; break; }
done: if (LockoutInfo != NULL) SamFreeMemory(LockoutInfo);
if (NameInfo != NULL) SamFreeMemory(NameInfo);
if (ReplicationInfo != NULL) SamFreeMemory(ReplicationInfo);
if (ServerRoleInfo != NULL) SamFreeMemory(ServerRoleInfo);
if (LogoffInfo != NULL) SamFreeMemory(LogoffInfo);
if (PasswordInfo != NULL) SamFreeMemory(PasswordInfo);
if (DomainSid != NULL) RtlFreeHeap(RtlGetProcessHeap(), 0, DomainSid);
if (DomainHandle != NULL) SamCloseHandle(DomainHandle);
if (ServerHandle != NULL) SamCloseHandle(ServerHandle);
return ApiStatus;}
/****************************************************************************** * NetUserModalsSet (NETAPI32.@) */NET_API_STATUSWINAPINetUserModalsSet(IN LPCWSTR servername, IN DWORD level, IN LPBYTE buf, OUT LPDWORD parm_err){ FIXME("(%s %d %p %p)\n", debugstr_w(servername), level, buf, parm_err); return ERROR_ACCESS_DENIED;}
/****************************************************************************** * NetUserSetGroups (NETAPI32.@) */NET_API_STATUSWINAPINetUserSetGroups(LPCWSTR servername, LPCWSTR username, DWORD level, LPBYTE buf, DWORD num_entries){ FIXME("(%s %s %lu %p %lu)\n", debugstr_w(servername), debugstr_w(username), level, buf, num_entries); return ERROR_ACCESS_DENIED;}
/****************************************************************************** * NetUserSetInfo (NETAPI32.@) */NET_API_STATUSWINAPINetUserSetInfo(LPCWSTR servername, LPCWSTR username, DWORD level, LPBYTE buf, LPDWORD parm_err){ UNICODE_STRING ServerName; UNICODE_STRING UserName; SAM_HANDLE ServerHandle = NULL; SAM_HANDLE AccountDomainHandle = NULL; SAM_HANDLE UserHandle = NULL; NET_API_STATUS ApiStatus = NERR_Success; NTSTATUS Status = STATUS_SUCCESS;
TRACE("(%s %s %lu %p %p)\n", debugstr_w(servername), debugstr_w(username), level, buf, parm_err);
if (parm_err != NULL) *parm_err = PARM_ERROR_NONE;
/* Check the info level */ switch (level) { case 0: case 1: case 2: case 3: case 4:// case 21: case 22: case 1003:// case 1005: case 1006: case 1007: case 1008: case 1009:// case 1010: case 1011: case 1012: case 1013: case 1014: case 1017: case 1018: case 1020: case 1024: case 1025: case 1051: case 1052: case 1053: break;
default: return ERROR_INVALID_LEVEL; }
if (servername != NULL) RtlInitUnicodeString(&ServerName, servername);
RtlInitUnicodeString(&UserName, username);
/* Connect to the SAM Server */ Status = SamConnect((servername != NULL) ? &ServerName : NULL, &ServerHandle, SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN, NULL); if (!NT_SUCCESS(Status)) { ERR("SamConnect failed (Status %08lx)\n", Status); ApiStatus = NetpNtStatusToApiStatus(Status); goto done; }
/* Open the Account Domain */ Status = OpenAccountDomain(ServerHandle, (servername != NULL) ? &ServerName : NULL, DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP | DOMAIN_READ_PASSWORD_PARAMETERS, &AccountDomainHandle); if (!NT_SUCCESS(Status)) { ERR("OpenAccountDomain failed (Status %08lx)\n", Status); ApiStatus = NetpNtStatusToApiStatus(Status); goto done; }
/* Open the User Account */ ApiStatus = OpenUserByName(AccountDomainHandle, &UserName, USER_ALL_ACCESS, &UserHandle); if (ApiStatus != NERR_Success) { ERR("OpenUserByName(%wZ) failed (ApiStatus %lu)\n", &UserName, ApiStatus); goto done; }
/* Set user information */ ApiStatus = SetUserInfo(UserHandle, buf, level, parm_err); if (ApiStatus != NERR_Success) { ERR("SetUserInfo failed (Status %lu)\n", ApiStatus); }
done: if (UserHandle != NULL) SamCloseHandle(UserHandle);
if (AccountDomainHandle != NULL) SamCloseHandle(AccountDomainHandle);
if (ServerHandle != NULL) SamCloseHandle(ServerHandle);
return ApiStatus;}
/* EOF */