home *** CD-ROM | disk | FTP | other *** search
- /*******************************************************************************/
- /* SCCSID: %W% %E% */
- /* */
- /* */
- /* OCO Source Materials */
- /* */
- /* Program number 5639-F93 */
- /* */
- /* (c) Copyright IBM Corp. 1987,1999 */
- /* */
- */
- /* */
- /*******************************************************************************/
- /*
- * (C) 1994 IBM Corporation
- * (P) 1994 IBM OS/2 LAN Server
- *
- * OCO Source Materials
- */
-
-
- /* Post ISO/CMVC Revision history:
- *
- * Flags prefix: f = feature d = defect
- *
- * Flag Fixer Date Tester Date Review Date Release
- * ---- -------- -------- ------- -------- ----------- ---------
- * @f00 f2175 TRK 93Dec09 TRK 93Dec09 93Dec11 ls 4.0
- * @d01 d6634 SYED 3-28-94
- * d4701 SL 02jun94
- * d9983 MEB 94Jul22 MEB 94Jul22 94Jul25 ls 4.0
- * d33038 VEC 96Mar03 VEC 96Mar03 96Mar03 ls 4.0
- *
- * DESCRIPTIONS:
- * f2175:
- * WUserPasswordSet3 changes.
- * d6634:
- * Update last logon and last logoff in UserSetInfo.
- * d4701:
- * Stop checking for (unsigned variables < 0).
- * d9983:
- * Add the ability to set the primary computer name in the
- * UserModalsSet level 101.
- *
- ******************************************************************************
- * ********* CHANGE HISTORY **************************************************
- *
- * Defect Flag Fixer Date Description
- * ------ ----- ------ -------- ---------------------------------------
- * 42799 @D05 JGC 12/12/96 Removethe change of d33038. It did no
- * work. Remove the change makes it work.
- * d43314 @D06 JGC 01/24/97 Remove the change of d42799, i.e., put
- * back of d33038 fix.
- * d43122 @D07 rcf 03/14/97 Detect change to null password
- *
- * f55952 @f08 lc 07/07/99 Changes to support Domain Wide UID feature
- */
-
- /*
- ******************************************************************************
- * USERAPI.C Second level functions for NetUser APIs
- *
- * The interface in this module should be same as defined
- * in summary.api except that it is purely local
- * (Thus there is no servername parameter).
- *
- * Functions:
- * UAdd, UserAdd
- * UserGetGroups
- * UserSetGroups
- * UserValidate, UserValidate2
- * UserPasswordSet
- * UserGetInfo
- * UserSetInfo
- * UserDel
- * UserEnum
- * UserGetModals
- * UserSetModals
- *
- * History:
- *
- * 10/6/87 HongLy Changes in NetPackString
- * 1. Do a NetPackString in order
- * 2. Do not put a NULL pointer in variable length
- * instead put a pointer to '\0';
- * 12/6/87 HongLy add script
- *
- * 10/17/88 Pradym Many changes and additions to conform to LM1.2
- * 01/25/89 Pradym Moved bunch of lower level functions to uasutil.c
- *
- *
- * WARNING:
- * A File Semaphore has been added (LOCKDBFILE,
- * UNLOCKDBFILE) IT IS NECESSARY TO GRAB THIS FIRST
- * BEFORE GRABBING MEMORY SEMAPHORE.
- * Memory semaphore must be released before doing DISK I/O.
- *
- */
-
- #define INCL_DOSMEMMGR
- #define INCL_DOSFILEMGR
- #define INCL_DOSSEMAPHORES
- #define INCL_DOSERRORS
- #define INCL_DOSPROCESS
- #include <os2.h>
-
- #include <ctype.h>
- #include <netcons.h>
- #include <icanon.h>
- #include <dos.h>
- #include <netlib.h>
- #include <neterr.h>
- #include <shares.h>
- #include <apiutil.h>
- #include <inetapi.h>
- #include <remutil.h>
- #include <rdrioctl.h> /* next three are required for srvinfo.h */
- #include <ncb.h>
- #include <netbuf.h>
- #include <server.h>
- #include <wksta.h>
- #include <api.h> /* GetServerSegs & FreeServerSegs */
- #include <resstats.h>
- #include <srvinfo.h>
- #include <access.h>
- #include <uascache.h>
- #include <apisec.h>
- #include <rnetapi.h>
- #include <crypt.h>
- #include <permit.h>
- #include <acfproto.h>
- #include <assert.h>
- #include "uasutil.h"
-
-
- API_FUNCTION FreeUserEntries(char far * username);
-
- /*
- * Local prototype
- */
- static int near vcopy(char far *, char far *, int);
- unsigned short SetHomeDir(unsigned short, char far *, char far *, unsigned short);
- unsigned short SetScriptPath(char far *, char far *, unsigned short);
-
- /*
- * UAdd -- Add a user name
- *
- * Following default values are used for level 1 calls.
- *
- * full_name usri1_name
- * usr_comment NULL
- * workstations NULL (means login allowed from any)
- * acct_expires TIMEQ_FOREVER (never expires)
- * max_storage USER_MAXSTORAGE_UNLIMITED
- * logon_hours Always
- * logon_server Domain Controller (Null_String)
- *
- * Array containing old passwords for history checking is initialized
- * to all 0xFFs in user record being added. The units_per_week is
- * UNITS_PER_WEEK for this release and user passed parameter in struct
- * user_info_2, if any, is ignored.
- *
- * Input:
- * buf filled with struct user_info_X (X = Level)
- * buflen size of buffer
- * level level of detail (must be 1 or 2)
- * home homedirectory
- * script logon script
- * fd net.acc file handle
- *
- * Output:
- * 0 -- success
- * NERR_GroupExists
- * NERR_ACFNoRoom
- * NERR_UserExists
- * NERR_FileIOFail
- *
- */
- int
- UAdd(buf, level, home, script, fd)
- char far *buf;
- short level;
- char far *home;
- char far *script;
- int fd;
- {
- #ifndef REMONLY
- int err;
- struct user_object far *uo;
- struct _userrec far *u;
- char priv;
- char far * name;
- char far * passwd;
- char far * comment;
- char far * buf_end;
- SEL sel;
- unsigned short full=TRUE; /* @f08a */
- unsigned short flags;
- unsigned long type;
- char far * p;
- long pos;
- long serial;
- char local_uname[UNLEN+1];
-
- if (level == LEVEL_1)
- name = ((struct user_info_1 far *)buf)->usri1_name;
- else
- name = ((struct user_info_2 far *)buf)->usri2_name;
-
- if (err = I_NetNameCanonicalize(NULL, name, (char far *)local_uname,
- sizeof(local_uname), NAMETYPE_USER, 0L))
- return ERROR_INVALID_PARAMETER;
-
- name = local_uname;
-
- /* Is name in group list */
- if (GroupId(name, &serial) >= 0 ) /* name exists */
- return NERR_GroupExists;
-
- if (err = DosAllocSeg(MAX_USER_SIZE, &sel, 0))
- return err;
- else {
- uo = (struct user_object far *) PTR(sel, 0);
- u = &uo->uo_record;
- buf_end = (char far *)(u + 1);
- }
-
- if (Ucb->hdr.num_users >= MAX_USERS)
- err = NERR_ACFNoRoom;
- else
- err = GetUserObject(fd, name, uo, &pos);
-
- if (err == 0) /* Duplicate Name */
- err = NERR_UserExists;
-
- if (err != NERR_UserNotFound)
- {
- DosFreeSeg(sel);
- return err;
- }
-
- /* zero the "err" variable so we won't be bitten unwittingly */
- err = 0;
-
- /* Ok ! no duplicate, copy the stuff into the u record */
- u->name[UNLEN] = '\0';
- strncpyf(u->name, name, UNLEN);
-
- /* common defaults for both levels */
- u->last_logon = u->last_logoff = 0L; /* 0 ==> unknown */
- u->bad_pw_count = u->num_logons = -1; /* -1 ==> unknown */
- u->code_page = 0;
- memsetf(u->logonhrs, (unsigned char) 0xFF, UNITS_PER_WEEK/8);
- memsetf(u->old_passwds, (unsigned char) 0xFF,sizeof(u->old_passwds));
- if (level == LEVEL_1)
- {
- passwd = ((struct user_info_1 far *)buf)->usri1_password;
- priv = (char) ((struct user_info_1 far *)buf)->usri1_priv;
- flags = ((struct user_info_1 far *)buf)->usri1_flags;
- comment = ((struct user_info_1 far *)buf)->usri1_comment;
- /* set defaults */
- URAppend (u, &buf_end, &u->full_name_o, name, MAXCOMMENTSZ,
- FALSE);
- URAppend (u, &buf_end, &u->usr_comment_o, NULL, 0, FALSE);
- URAppend (u, &buf_end, &u->parms_o, NULL, 0, FALSE);
- URAppend (u, &buf_end, &u->workstation_o, NULL, 0, FALSE);
- /* default logon_server is "" ==> domain controller */
- URAppend (u, &buf_end, &u->logon_server_o, NULL, 0, FALSE);
- u->acct_expires = TIMEQ_FOREVER;
- u->max_storage = USER_MAXSTORAGE_UNLIMITED;
- u->user.uc0_auth_flags = 0;
- u->country_code = 0;
- u->code_page = 0;
- GetCountryCode((unsigned short far *) &u->country_code);
- }
- else
- {
- passwd = ((struct user_info_2 far *)buf)->usri2_password;
- priv = (char) ((struct user_info_2 far *)buf)->usri2_priv;
- flags = ((struct user_info_2 far *)buf)->usri2_flags;
- comment = ((struct user_info_2 far *)buf)->usri2_comment;
-
- /* set level 2 stuff */
- if (((struct user_info_2 far *)buf)->usri2_full_name == NULL)
- URAppend(u, &buf_end, &u->full_name_o, NULL, 0, FALSE);
- else
- URAppend(u, &buf_end, &u->full_name_o,
- ((struct user_info_2 far *)buf)->usri2_full_name,
- MAXCOMMENTSZ, FALSE);
- if (((struct user_info_2 far *)buf)->usri2_usr_comment == NULL)
- URAppend(u, &buf_end, &u->usr_comment_o,
- NULL, 0, FALSE);
- else
- {
- URAppend(u, &buf_end, &u->usr_comment_o,
- ((struct user_info_2 far *)buf)->usri2_usr_comment,
- MAXCOMMENTSZ, FALSE);
- }
- if (((struct user_info_2 far *)buf)->usri2_parms == NULL)
- URAppend(u, &buf_end, &u->parms_o, NULL, 0, FALSE);
- else
- URAppend(u, &buf_end, &u->parms_o,
- ((struct user_info_2 far *)buf)->usri2_parms,
- MAXCOMMENTSZ, FALSE);
-
- u->acct_expires =
- ((struct user_info_2 far *)buf)->usri2_acct_expires;
- u->max_storage =
- ((struct user_info_2 far *)buf)->usri2_max_storage;
- /* space delimited computer names terminated by \0 */
- if (((struct user_info_2 far *)buf)->usri2_workstations != NULL)
- {
- p = ((struct user_info_2 far *)buf)->usri2_workstations;
- err = URAppend (u, &buf_end, &u->workstation_o, p,
- MAXWORKSTATIONS * (CNLEN+1), TRUE);
- }
- else
- URAppend (u, &buf_end, &u->workstation_o, NULL, 0, FALSE);
- /* logon_hours == NULL ==> Access allowed at All times */
- p = ((struct user_info_2 far *)buf)->usri2_logon_hours;
- if ( p != NULL )
- memcpyf(u->logonhrs, p, UNITS_PER_WEEK/8);
- /* set the logon server if given. NULL ==> domain controller */
- /* Note that \\* means any server can be used as logon server */
- p = ((struct user_info_2 far *)buf)->usri2_logon_server;
- if (p != NULL && p[0] != '\0')
- {
- if (p[0] == '\\' && p[1] == '\\' && p[2] == '*' && strlenf(p) == 3)
- URAppend(u, &buf_end,&u->logon_server_o,p,UNCLEN,FALSE);
- else if ( I_NetPathType(NULL, p, &type, 0L) ||
- type != ITYPE_UNC_COMPNAME)
- err = ERROR_INVALID_PARAMETER;
- else
- URAppend(u, &buf_end,&u->logon_server_o,p,UNCLEN,FALSE);
- }
- else
- URAppend(u, &buf_end, &u->logon_server_o, NULL, 0, FALSE);
- u->country_code = ((struct user_info_2 far *)buf)->usri2_country_code;
- u->code_page = ((struct user_info_2 far *)buf)->usri2_code_page;
- u->user.uc0_auth_flags = ((struct user_info_2 far *)buf)->usri2_auth_flags;
- }
-
- if (err)
- {
- DosFreeSeg(sel);
- return err;
- }
-
- if (UseEncryption) {
- /* encrypted password */
- if (err = CryptUID(ENCR_KEY, u->user.uc0_guid.guid_uid, passwd, u->passwd))
- {
- DosFreeSeg(sel);
- return(err);
- }
- }
- else
- /* plain text password */
- memcpyf(u->passwd, passwd, PWLEN + 1);
-
- u->user.uc0_priv = priv;
-
- if (home != NULL)
- URAppend (u, &buf_end, &u->directory_o, home, PATHLEN, FALSE);
- else
- URAppend (u, &buf_end, &u->directory_o, NULL, 0, FALSE);
-
- if (comment != NULL)
- URAppend (u, &buf_end, &u->comment_o, comment, MAXCOMMENTSZ, FALSE);
- else
- URAppend (u, &buf_end, &u->comment_o, NULL, 0, FALSE);
-
- if (script != NULL)
- URAppend (u, &buf_end, &u->script_o, script, PATHLEN, FALSE);
- else
- URAppend (u, &buf_end, &u->script_o, NULL, 0, FALSE);
-
- /* Warning: bit0 must be 1 for this release, enforced by UI */
- u->flags = flags;
- u->last = time_now();
- memsetf(u->user.uc0_groups, 0, sizeof(u->user.uc0_groups));
-
- /* level 200 add uses the supplied serial number as opposed */ /* @f08a */
- /* to the next available one from the hash table. Also, set */ /* @f08a */
- /* full flag to indicate serial number supplied is to be used */ /* @f08a */
-
- if (level == LEVEL_200) /* @f08a */
- { /* @f08a */
- u->user.uc0_guid.guid_serial = /* @f08a */
- ((struct user_info_200 far *)buf)->usri200_serial; /* @f08a */
- full = FULL_USE_SERIAL; /* @f08a */
- } /* @f08a */
- else /* @f08a */
- { /* @f08a */
- u->user.uc0_guid.guid_serial =
- UserHashTbl[u->user.uc0_guid.guid_uid].uh_serial;
- } /* @f08a */
-
- /* before writing the record on disk zero the 10 resvd bytes of GUID */
- memsetf(u->user.uc0_guid.guid_rsvd, 0, 10);
-
- u->size = (char far *)buf_end - (char far *)u;
-
- /* mark its membership in one of the special groups */
- if (uo->uo_record.user.uc0_priv == USER_PRIV_ADMIN)
- MARKUSE(uo->uo_record.user.uc0_groups, Ucb->AdminsId);
- else if (uo->uo_record.user.uc0_priv == USER_PRIV_GUEST)
- MARKUSE(uo->uo_record.user.uc0_groups, Ucb->GuestsId);
- else if (uo->uo_record.user.uc0_priv == USER_PRIV_USER)
- MARKUSE(uo->uo_record.user.uc0_groups, Ucb->UsersId);
-
- pos = 0L;
- if (err = WriteUserObject (fd, &pos, uo, full)) /* @f08c */
- {
- DosFreeSeg(sel);
- return err;
- }
-
- Ucb->usercnt++;
-
- DosFreeSeg(sel);
- return 0;
- #else
- return ERROR_NOT_SUPPORTED;
- #endif /* REMONLY */
-
- /* quiet the compiler */
- if(buf || level || home || script || fd);
- }
-
- /*
- * UserAdd -- Adding a user
- *
- * Since this is mostly a file-IO, we would not memory seg unless
- * it is necessary
- *
- * Input:
- * buf struct user_info_1 or user_info_2
- * rootdir path (relative/abs) for home_dir
- * level level of info being supplied
- *
- * Output:
- * NERR_Success ( 0 )
- * ERROR_INVALID_LEVEL
- * NERR_BufTooSmall
- * NERR_UserExists
- * NERR_GroupExists
- * NERR_ACFNoRoom
- * NERR_ACFFileIOFail
- */
- int
- UserAdd(buf, rootdir, level)
- char far *buf;
- char far *rootdir;
- short level;
- {
- #ifndef REMONLY
- int err = 0;
- int fd;
- char homedir[PATHLEN+1];
- char script[PATHLEN+1];
- char far * name;
- char far * home_dir;
- char far * scriptp;
- struct user_info_1 far *user = (struct user_info_1 far *)buf;
- struct user_info_2 far *user2 = (struct user_info_2 far *)buf;
- char tmp[MAXWORKSTATIONS * (CNLEN+1)];
- unsigned short count;
- unsigned short flags;
- char far * workstn;
-
-
- if (level == LEVEL_1)
- name = ((struct user_info_1 far *)buf)->usri1_name;
- else
- name = ((struct user_info_2 far *)buf)->usri2_name;
-
- /* Validate the user name */
- if (I_NetNameValidate(NULL, name, NAMETYPE_USER, 0L) )
- return NERR_BadUsername;
-
- /* Validate the data */
- if (err = ValidateUser(buf, level) )
- return err;
-
- if (level == LEVEL_1)
- {
- home_dir = ((struct user_info_1 far *)buf)->usri1_home_dir;
- scriptp = ((struct user_info_1 far *)buf)->usri1_script_path;
- flags = ((struct user_info_1 far *)buf)->usri1_flags;
- }
- else
- {
- home_dir = ((struct user_info_2 far *)buf)->usri2_home_dir;
- scriptp = ((struct user_info_2 far *)buf)->usri2_script_path;
- flags = ((struct user_info_2 far *)buf)->usri2_flags;
- workstn = ((struct user_info_2 far *)buf)->usri2_workstations;
- }
-
- if ( ((level == LEVEL_2) || (level == LEVEL_200)) && workstn != NULL ) /* @f08c */
- {
- if (strlenf(workstn) > MAXWORKSTATIONS *(CNLEN+1))
- return ERROR_INVALID_PARAMETER;
- strcpyf(tmp, workstn);
- if (I_NetListCanonicalize(NULL,
- tmp,
- LIST_DELIMITER_STR_API,
- workstn,
- strlenf(workstn)+1,
- &count,
- NULL,
- 0,
- NAMETYPE_COMPUTER|OUTLIST_TYPE_API|
- INLC_FLAGS_CANONICALIZE) ||
- (count > MAXWORKSTATIONS))
- {
- strcpyf(workstn, tmp);
- return ERROR_INVALID_PARAMETER;
- }
- }
-
- if ( !(err = SetHomeDir(flags, home_dir, homedir, sizeof(homedir))) )
- err = SetScriptPath(scriptp, script, sizeof(script));
-
- if (err == NERR_Success)
- {
- if ((err = OpenAccount(&fd)) == NERR_Success)
- {
- /* add a new user record */
- LOCKDBFILE();
- LOCKUSEG();
- err = UAdd(buf, level, homedir, script, fd);
- UNLOCKUSEG();
- UNLOCKDBFILE();
- CloseAccount(fd);
- }
- }
- /* restore workstation list */
- if ( ((level == LEVEL_2) || (level == LEVEL_200)) && workstn != NULL ) /* @f08c */
- strcpyf(workstn, tmp);
-
- return err;
- #else
- return ERROR_NOT_SUPPORTED;
- #endif /* REMONLY */
-
- /* quiet the compiler */
- if (buf || rootdir || level)
- ;
- }
-
- /*
- * UserGetGroups -- Get All groups name the user belongs to
- *
- * Input:
- * Uname -- user name
- * level -- level of detail
- * buf
- * buflen -- length of buffer
- *
- * Output:
- * entries -- number of entries in returned buffer
- * total -- number of entries available
- *
- * Returns:
- * 0 -- success
- * NERR_ACFFileIOFail
- * ERROR_INVALID_LEVEL
- * NERR_BufTooSmall
- * ERROR_MORE_DATA
- * NERR_UserNotFound
- */
- int
- UserGetGroups(uname, buf, buflen, entries, total)
- const char far *uname;
- char far *buf;
- unsigned short buflen;
- unsigned short far *entries;
- unsigned short far *total;
- {
- #ifndef REMONLY
- struct user_object far *uo;
- SEL sel;
- int err = 0;
- int fd;
- int avail;
- char far *group;
- char local_uname[UNLEN+1];
- int i;
- int j;
- char c;
- long pos;
-
-
- if (err = I_NetNameCanonicalize(NULL, uname, (char far *)local_uname,
- sizeof(local_uname), NAMETYPE_USER, 0L))
- return NERR_UserNotFound;
-
- if (err = OpenAccount(&fd))
- return err;
-
- if (err = DosAllocSeg(MAX_USER_SIZE, &sel, 0))
- {
- CloseAccount(fd);
- return err;
- }
- else
- {
- uo = (struct user_object far *) PTR(sel, 0);
- LOCKDBFILE();
- err = GetUserObject(fd, (char far *)local_uname, uo, &pos);
- if (!err)
- group = uo->uo_record.user.uc0_groups;
- UNLOCKDBFILE();
- }
-
- if (err)
- {
- CloseAccount(fd);
- DosFreeSeg(sel);
- return err;
- }
-
- /* group is ptr to the group bit map let's enumerate it */
-
- *entries =0;
- *total = 0;
- avail = buflen/sizeof(struct group_info_0);
- for (i=0; i < MAXGROUP/8; i++ )
- {
- c = group[i];
- for (j=0; j < 8; j++, c >>= 1 )
- if (c & 1) { /* True */
- // ASSERT((c = Ucb->group[i*8+j].name[0]) != REC_DELETE
- // && c != REC_EMPTY, nprintf("Internal bug 3\n"))
-
- if (avail > 0) {
- memcpyf(buf, (char far *)&Ucb->group[i*8+j]
- , sizeof(struct group_info_0) );
- buf += sizeof(struct group_info_0);
- avail --;
-
- (*entries)++;
- }
- (*total)++;
- }
- }
-
- CloseAccount(fd);
- DosFreeSeg(sel);
- if (*total > *entries)
- return ERROR_MORE_DATA;
- else
- return NERR_Success;
- #else
- return ERROR_NOT_SUPPORTED;
- #endif /* REMONLY */
-
- /* quiet the compiler */
- if (uname || buf || buflen || entries || total);
- }
-
- /*
- * UserSetGroups Replace existing group map of the named user
- * with a new one making this user member of groups
- * specified in buffer.
- *
- * Input:
- * uname user name
- * level level of detail
- * buf Buffer filled with struct group_info_0
- * buflen length of buffer
- * entries number of entries in supplied buffer
- *
- * Output:
- *
- *
- * Returns:
- * 0 -- success
- * NERR_ACFFileIOFail
- * ERROR_INVALID_LEVEL
- * NERR_BufTooSmall
- * ERROR_MORE_DATA
- * NERR_UserNotFound
- */
- int
- UserSetGroups(uname, buf, buflen, entries)
- const char far *uname;
- char far *buf;
- unsigned short buflen;
- unsigned short entries;
- {
- #ifndef REMONLY
- struct user_object far *uo;
- SEL sel;
- struct group_info_0 far * gname;
- int err = 0;
- USER far * user;
- short gid;
- int fd;
- long pos;
- char local_uname[UNLEN+1];
-
-
- if ( (buflen/sizeof(struct group_info_0)) < entries )
- return NERR_BufTooSmall;
-
- if (err = I_NetNameCanonicalize(NULL, uname, (char far *)local_uname,
- sizeof(local_uname), NAMETYPE_USER, 0L))
- return NERR_UserNotFound;
-
- if (err = OpenAccount(&fd))
- return err;
-
- if (err = DosAllocSeg(MAX_USER_SIZE, &sel, 0))
- {
- CloseAccount(fd);
- return err;
- }
- else
- uo = (struct user_object far *) PTR(sel, 0);
-
- LOCKDBFILE();
- if (err = GetUserObject(fd, (char far *)local_uname, uo, &pos))
- {
- UNLOCKDBFILE();
- CloseAccount(fd);
- DosFreeSeg(sel);
- return err;
- }
-
- memsetf(uo->uo_record.user.uc0_groups, 0,
- sizeof(uo->uo_record.user.uc0_groups));
-
- gname = (struct group_info_0 far *) buf;
-
- /* now prepare new map */
- while( entries-- )
- {
- if (err = I_NetNameCanonicalize(NULL, gname->grpi0_name,
- (char far *)gname->grpi0_name,
- GNLEN+1, NAMETYPE_GROUP, 0L))
- {
- /* treat bad name same as Group not found */
- err = NERR_GroupNotFound;
- }
- else if (!(GetGroupId(Ucb->group, gname->grpi0_name, &gid)))
- {
- /* return error if Special Group found */
- if ((gid != Ucb->AdminsId) &&
- (gid != Ucb->GuestsId) &&
- (gid != Ucb->LocalId) &&
- (gid != Ucb->UsersId))
- MARKUSE(uo->uo_record.user.uc0_groups, gid);
- else
- err = NERR_SpeGroupOp;
- }
- else
- err = NERR_GroupNotFound;
-
- if (err)
- {
- UNLOCKDBFILE();
- CloseAccount(fd);
- DosFreeSeg(sel);
- return err;
- }
- gname++;
- }
- /* mark its membership in one of the special groups */
- if (uo->uo_record.user.uc0_priv == USER_PRIV_ADMIN)
- MARKUSE(uo->uo_record.user.uc0_groups, Ucb->AdminsId);
- else if (uo->uo_record.user.uc0_priv == USER_PRIV_GUEST)
- MARKUSE(uo->uo_record.user.uc0_groups, Ucb->GuestsId);
- else if (uo->uo_record.user.uc0_priv == USER_PRIV_USER)
- MARKUSE(uo->uo_record.user.uc0_groups, Ucb->UsersId);
-
- err = WriteUserObject (fd, &pos, uo, TRUE);
-
- LOCKUSEG();
- user = FindUidInCache (uo->uo_record.user.uc0_guid.guid_uid,
- uo->uo_record.user.uc0_guid.guid_serial);
- if ( err == 0 && user)
- {
- /* update the cache */
- memcpyf(user->uc0_groups, uo->uo_record.user.uc0_groups,
- sizeof(user->uc0_groups));
- KickPinballSem();
- }
- UNLOCKUSEG();
-
- UNLOCKDBFILE();
- DosFreeSeg(sel);
- CloseAccount(fd);
- return err;
- #else
- return ERROR_NOT_SUPPORTED;
- #endif /* REMONLY */
-
- /* quiet the compiler */
- if (uname || buf || buflen || entries);
- }
-
-
- /*
- * UserPasswordSet
- *
- * passlen password length (when it was in plain text form)
- */
- int
- UserPasswordSet(uname, old, new, passlen, uo, pos, fd, clevel)
- char far *uname;
- char far *old; /* old password */
- char far *new; /* new password */
- unsigned short passlen;
- struct user_object far *uo;
- long far * pos;
- int fd;
- unsigned short clevel;
- {
- # define NULL_ESTD "\xaa\xd3\xb4\x35\xb5\x14\x04\xee\xaa\xd3\xb4\x35\xb5\x14\x04\xee" /*@D07*/
- #ifndef REMONLY
- struct _userrec far *u;
- register int err = 0;
- unsigned long current_time;
- int saverr = 0;
- int nullpw = FALSE; /*@D07*/
- u = &uo->uo_record;
-
- if (memcmpf(NULL_ESTD, new, ENCRYPTED_PWLEN)) nullpw = FALSE; /*@D07*/
- else nullpw = TRUE; /*New PW is NULL*/ /*@D07*/
- if /* this is NOT from a remote call to WUserPasswordSet3 */
- (old) // @f00a
- {
-
- if (UseEncryption)
- {
- /* encrypting server, determine if it has the right */
- if (CryptUID(ENCR_KEY, u->user.uc0_guid.guid_uid, old, old))
- return ERROR_ACCESS_DENIED;
- else if (memcmpf(u->passwd, old, ENCRYPTED_PWLEN))
- saverr = ERROR_INVALID_PASSWORD;
- else if (CryptUID(ENCR_KEY, u->user.uc0_guid.guid_uid, new, new))
- return ERROR_ACCESS_DENIED;
- }
- else
- {
- /* non encrypting server */
- if (strncmpf(u->passwd, old, PWLEN + 1))
- saverr = ERROR_INVALID_PASSWORD;
- }
- }
- else // @f00a
- {
- if (UseEncryption &&
- CryptUID(ENCR_KEY, u->user.uc0_guid.guid_uid, new, new))
- return ERROR_ACCESS_DENIED;
- }
-
- current_time = time_now();
- /*
- * Bypass all restrictions when called from NETLOGON service.
- */
- if (clevel != ACCESS_NETLOGON)
- {
- if ((unsigned long)(u -> acct_expires) < current_time)
- return NERR_AccountExpired;
-
- if (!(u->flags & UF_PASSWD_NOTREQD)) // password is required
- {
- /*
- * Following restrictions will be enforced only if the
- * password is required i.e. UF_PASSWORD_NOTREQD flag
- * is not set on this account.
- */
- if (u->flags & UF_PASSWD_CANT_CHANGE)
- return NERR_PasswordCantChange;
- if ( (current_time - u->last) < Ucb->hdr.min_passwd_age )
- return NERR_PasswordTooRecent;
- if (CheckPasswdHistory(new, u->old_passwds, UseEncryption))
- return NERR_PasswordHistConflict;
- if (passlen < Ucb->hdr.min_passwd_len)
- return NERR_PasswordTooShort;
- if ((nullpw) && (0 < Ucb->hdr.min_passwd_len)) /*@D07*/
- return NERR_PasswordTooShort; /*@D07*/
- }
- else // password is not required
- {
- if (passlen != IGNORE_PASSWDLEN)
- {
- /*
- * If password is not required on this account then
- * the caller can either specify a null password ("")
- * or supply one whichis not shorter than minimum
- * password length modal. It is relevant only for
- * LM2.0 clients.
- */
- if ( (passlen != 0) && (passlen < Ucb->hdr.min_passwd_len) )
- return NERR_PasswordTooShort;
- }
- } // LM1.X clients can bypass modal restrictions
- }
-
- if (saverr)
- {
- /* We check other password restrictions and return those errors
- * as appropriate before we return an error that the password
- * sent was incorrect. We also pause for INTRUDER_DELAY (3 seconds)
- * before returning to slow down hackers trying to figure out a
- * password. We probably need to do an audit of this failure as
- * well, but that's DCR material since it would mean defining a
- * new audit entry.
- */
- DosSleep(INTRUDER_DELAY);
- return saverr;
- }
-
- SavePassword(u->old_passwds, u->passwd, Ucb->hdr.passwd_hist_len);
- memcpyf(u->passwd, new, ENCRYPTED_PWLEN);
- u->last = current_time;
- LOCKDBFILE();
- err = WriteUserObject(fd, pos, uo, TRUE);
- UNLOCKDBFILE();
- return err;
-
- #else
- return ERROR_NOT_SUPPORTED;
- #endif /* REMONLY */
-
- /* quiet the compiler */
- if (uname || old || new || passlen || fd || uo || pos || clevel);
- }
-
- /*
- * UserGetInfo -- Get user's Information
- * Note That we will not return Password
- *
- * Input:
- * uname - user name
- * level -- level of detail {0, 1, 2, 10, 11}
- * buf, buflen
- * Output:
- * total -- number of bytes available
- *
- * Returns:
- * 0 -- success
- * ERROR_INVALID_LEVEL
- * NERR_BufTooSmall
- * ERROR_MORE_DATA
- * NERR_UserNotFound
- */
- int
- UserGetInfo(uname, level, buf, buflen, total)
- char far *uname;
- short level;
- char far *buf;
- unsigned short buflen;
- unsigned short far *total;
- {
- #ifndef REMONLY
- int fd;
- struct user_info_1 far *user;
- struct user_info_2 far *user2;
- struct user_info_10 far *user10;
- struct user_info_11 far *user11;
- struct user_object far *uo;
- struct _userrec far *u;
- SEL sel;
- unsigned short info_size; /* @f08a */
- int err = 0;
- int sts;
- char far *fixed_size_end; /* end of fixed size data */ /* @f08a */
- char far *end = buf+buflen; /* end of buffer */
- long pos;
- char local_uname[UNLEN+1];
-
-
- if (err = I_NetNameCanonicalize(NULL, uname, (char far *)local_uname,
- sizeof(local_uname), NAMETYPE_USER, 0L))
- return NERR_UserNotFound;
-
- /* open the named file */
- if (err = OpenAccount(&fd))
- return err;
- if (err = DosAllocSeg(MAX_USER_SIZE, &sel, 0))
- {
- CloseAccount(fd);
- return err;
- }
- else {
- uo = (struct user_object far *) PTR(sel, 0);
- u = &uo->uo_record;
- }
-
- LOCKDBFILE();
- sts = GetUserObject(fd, local_uname, uo, &pos);
- CloseAccount(fd);
- UNLOCKDBFILE();
-
- if (sts)
- {
- DosFreeSeg(sel);
- return sts;
- }
-
- if (level == LEVEL_0 ) {
- *total = sizeof (struct user_info_0 );
- if (buflen < sizeof(struct user_info_0) )
- err = NERR_BufTooSmall;
- else
- strcpyf(buf, local_uname);
- }
- else if (level == LEVEL_1) {
- *total = sizeof(struct user_info_1) +
- strlenf( STRING(u, directory_o)) + 1 +
- strlenf( STRING(u, comment_o)) + 1 +
- strlenf( STRING(u, script_o)) + 1;
-
- if (buflen < sizeof(struct user_info_1) )
- err = NERR_BufTooSmall;
- else {
- user = (struct user_info_1 far *)buf;
- strcpyf(user->usri1_name, local_uname);
- strcpyf(user->usri1_password, Null_Passwd);
-
- // @D06:begin: Put back d33038 fix.
- if (u->last) // d33038
- user->usri1_password_age = time_now() - u->last;
- else // d33038
- user->usri1_password_age = 0; // d33038
- // @D06:end
-
- user->usri1_priv = u->user.uc0_priv;
-
- user->usri1_home_dir = STRING (u, directory_o);
- NetPackString(&user->usri1_home_dir,
- (char far *)(user+1), &end);
- user->usri1_comment = STRING (u, comment_o);
- NetPackString(&user->usri1_comment,
- (char far *)(user+1), &end);
- user->usri1_flags = u->flags;
- user->usri1_script_path = STRING (u, script_o);
- NetPackString(&user->usri1_script_path,
- (char far *)(user+1), &end);
- }
- }
- else if ((level == LEVEL_2) || (level == LEVEL_200)) { /* @f08c */
- if (level == LEVEL_2) /* @f08a */
- { /* @f08a */
- info_size = sizeof(struct user_info_2); /* @f08a */
- } /* @f08a */
- else /* @f08a */
- { /* @f08a */
- info_size = sizeof(struct user_info_200); /* @f08a */
- } /* @f08a */
- *total = info_size + /* @f08c */
- strlenf( STRING( u, directory_o)) +1 +
- strlenf( STRING( u, comment_o))+1 +
- strlenf( STRING( u, script_o))+1 +
- strlenf( STRING( u, usr_comment_o))+1 +
- strlenf( STRING( u, full_name_o))+1 +
- strlenf( STRING( u, parms_o))+1 +
- strlenf( STRING( u, workstation_o))+1 +
- strlenf( STRING( u, logon_server_o))+1 +
- UNITS_PER_WEEK/8;
-
-
- if (buflen < info_size ) /* @f08c */
- err = NERR_BufTooSmall;
- else {
- user2 = (struct user_info_2 far *)buf;
- fixed_size_end = buf+info_size; /* @f08a */
- strcpyf(user2->usri2_name, local_uname);
- strcpyf(user2->usri2_password, Null_Passwd);
-
- // @D06:begin: Put back d33038 fix.
- if (u->last) // d33038
- user2->usri2_password_age = time_now() - u->last;
- else // d33038
- user2->usri2_password_age = 0; // d33038
- // @D06:end
-
- user2->usri2_priv = u->user.uc0_priv;
-
- user2->usri2_home_dir = STRING(u, directory_o);
- NetPackString(&user2->usri2_home_dir,
- fixed_size_end, &end); /* @f08c */
- user2->usri2_comment = STRING (u, comment_o);
- NetPackString(&user2->usri2_comment,
- fixed_size_end, &end); /* @f08c */
- user2->usri2_flags = u->flags;
- user2->usri2_script_path = STRING (u, script_o);
- NetPackString(&user2->usri2_script_path,
- fixed_size_end, &end); /* @f08c */
- user2->usri2_full_name = STRING (u, full_name_o);
- NetPackString(&user2->usri2_full_name,
- fixed_size_end, &end); /* @f08c */
- user2->usri2_usr_comment = STRING (u, usr_comment_o);
- NetPackString(&user2->usri2_usr_comment,
- fixed_size_end, &end); /* @f08c */
- user2->usri2_parms = STRING (u, parms_o);
- NetPackString(&user2->usri2_parms,
- fixed_size_end, &end); /* @f08c */
- /* workstations go here */
- user2->usri2_workstations = STRING (u, workstation_o);
- NetPackString(&user2->usri2_workstations,
- fixed_size_end, &end); /* @f08c */
- user2->usri2_last_logon= u->last_logon;
- user2->usri2_last_logoff = u->last_logoff;
- user2->usri2_bad_pw_count = u->bad_pw_count;
- user2->usri2_num_logons = u->num_logons;
- user2->usri2_max_storage = u->max_storage;
- user2->usri2_acct_expires = u->acct_expires;
- user2->usri2_logon_hours = u->logonhrs;
- NetPackBitmap(&user2->usri2_logon_hours,
- fixed_size_end, &end, UNITS_PER_WEEK/8); /* @f08c */
- /* logon server go here */
- user2->usri2_logon_server = STRING (u, logon_server_o);
- NetPackString(&user2->usri2_logon_server,
- fixed_size_end, &end); /* @f08c */
- user2->usri2_country_code = u->country_code;
- user2->usri2_code_page = u->code_page;
- user2->usri2_auth_flags = u->user.uc0_auth_flags;
- user2->usri2_units_per_week = UNITS_PER_WEEK;
-
- /* level 200 asks that we return the user's */ /* @f08a */
- /* serial number as well. */ /* @f08a */
- if (level == LEVEL_200) /* @f08a */
- { /* @f08a */
- ((struct user_info_200 far *)buf)->usri200_serial = /* @f08a */
- u->user.uc0_guid.guid_serial; /* @f08a */
- } /* @f08a */
- }
- }
- else if (level == LEVEL_10) {
- *total = sizeof(struct user_info_10) +
- strlenf( STRING (u, comment_o))+1 +
- strlenf( STRING (u, usr_comment_o))+1 +
- strlenf( STRING (u, full_name_o))+1;
-
-
- if (buflen < sizeof(struct user_info_10) )
- err = NERR_BufTooSmall;
- else {
- user10 = (struct user_info_10 far *)buf;
- strcpyf(user10->usri10_name, local_uname);
-
- user10->usri10_comment = STRING (u, comment_o);
- NetPackString(&user10->usri10_comment,
- (char far *)(user10+1), &end);
-
- user10->usri10_usr_comment = STRING(u, usr_comment_o);
- NetPackString(&user10->usri10_usr_comment,
- (char far *)(user10+1), &end);
-
- user10->usri10_full_name = STRING(u, full_name_o);
- NetPackString(&user10->usri10_full_name,
- (char far *)(user10+1), &end);
- }
- }
- else if (level == LEVEL_11) {
- *total = sizeof(struct user_info_11) +
- strlenf( STRING (u, comment_o))+1 +
- strlenf( STRING (u, usr_comment_o))+1 +
- strlenf( STRING (u, full_name_o))+1 +
- strlenf( STRING (u, directory_o))+1 +
- strlenf( STRING (u, logon_server_o))+1 +
- strlenf( STRING (u, workstation_o))+1 +
- strlenf( STRING (u, parms_o))+1 +
- UNITS_PER_WEEK/8;
-
-
- if (buflen < sizeof(struct user_info_11) )
- err = NERR_BufTooSmall;
- else {
- user11 = (struct user_info_11 far *)buf;
- strcpyf(user11->usri11_name, local_uname);
-
- // @D06:begin: Put back d33038 fix.
- if (u->last) // d33038
- user11->usri11_password_age = time_now() - u->last;
- else // d33038
- user11->usri11_password_age = 0; // d33038
- // @D06:end
-
- user11->usri11_priv = u->user.uc0_priv;
- user11->usri11_auth_flags = u->user.uc0_auth_flags;
-
- user11->usri11_comment = STRING (u, comment_o);
- NetPackString(&user11->usri11_comment,
- (char far *)(user11+1), &end);
- user11->usri11_usr_comment = STRING (u, usr_comment_o);
- NetPackString(&user11->usri11_usr_comment,
- (char far *)(user11+1), &end);
- user11->usri11_full_name = STRING (u, full_name_o);
- NetPackString(&user11->usri11_full_name,
- (char far *)(user11+1), &end);
- user11->usri11_home_dir = STRING (u, directory_o);
- NetPackString(&user11->usri11_home_dir,
- (char far *)(user11+1), &end);
- user11->usri11_parms = STRING (u, parms_o);
- NetPackString(&user11->usri11_parms,
- (char far *)(user11+1), &end);
- user11->usri11_last_logon= u->last_logon;
- user11->usri11_last_logoff = u->last_logoff;
- user11->usri11_bad_pw_count = u->bad_pw_count;
- user11->usri11_num_logons = u->num_logons;
- user11->usri11_country_code = u->country_code;
- user11->usri11_code_page = u->code_page;
- user11->usri11_max_storage = u->max_storage;
- user11->usri11_units_per_week = UNITS_PER_WEEK;
- /* logon server go here */
- user11->usri11_logon_server =
- STRING (u, logon_server_o);
- NetPackString(&user11->usri11_logon_server,
- (char far *)(user11+1), &end);
- /* workstations go here */
- user11->usri11_workstations = STRING(u, workstation_o);
- NetPackString(&user11->usri11_workstations,
- (char far *)(user11+1), &end);
- user11->usri11_logon_hours = u->logonhrs;
- NetPackBitmap(&user11->usri11_logon_hours,
- (char far *)(user11+1), &end, UNITS_PER_WEEK/8);
- }
- }
-
- DosFreeSeg(sel);
- if (!err && (*total > buflen))
- return ERROR_MORE_DATA;
-
- return err;
- #else
- return ERROR_NOT_SUPPORTED;
- #endif /* REMONLY */
-
- /* quiet the compiler */
- if (uname || level || buf || buflen || total);
-
- }
-
- /*
- * UserSetInfo -- SetInformation
- *
- * Password update restrictions are enforced if the password is
- * not NULL_SETINFO_PASSWORD.
- *
- * Input:
- * uname - user name
- * buf, buflen
- * paramnum -- parameter number 0 (means whole structure)
- * passlen length of password (when it was plain text)
- * last_admin flag indicating if it is last admin account
- *
- * Returns:
- * 0 -- success
- * ERROR_INVALID_LEVEL
- * NERR_BufTooSmall
- * ERROR_MORE_DATA
- */
- int
- UserSetInfo( uname, buf, parmnum, rootdir, level, passlen, last_admin)
- char far *uname;
- char far *buf;
- int parmnum;
- char far *rootdir;
- short level;
- unsigned short passlen;
- unsigned short last_admin;
- {
- #ifndef REMONLY
- int fd;
- struct user_info_1 far *user = (struct user_info_1 far *)buf;
- struct user_info_2 far *usr2 = (struct user_info_2 far *)buf;
- struct _userinfo far *u;
- struct user_object far *uo;
- SEL sel;
- USER far *user1;
- unsigned long type = 0;
- unsigned short full=TRUE; /* @f08a */
- unsigned short old_priv;
- unsigned short new_priv;
- int err = 0;
- unsigned short flags;
- char usr_passwd[ENCRYPTED_PWLEN];
- char far * home;
- char far * script;
- char far * rem;
- unsigned short count;
- long pos;
- char local_uname[UNLEN+1];
-
-
- if (parmnum == U1_ALL && (err = ValidateUser(buf, level)) )
- return err;
-
- if (err = I_NetNameCanonicalize(NULL, uname, (char far *)local_uname,
- sizeof(local_uname), NAMETYPE_USER, 0L))
- return NERR_UserNotFound;
-
- /* open the named file */
- if (err = OpenAccount(&fd))
- return err;
- if (err = DosAllocSeg(sizeof (struct _userinfo) + MAX_USER_SIZE, &sel, 0))
- {
- CloseAccount(fd);
- return err;
- }
- else {
- uo = (struct user_object far *)PTR(sel, 0);
- u = (struct _userinfo far *) PTR(sel, MAX_USER_SIZE);
- }
-
- LOCKDBFILE();
- if (err = GetUserObject (fd, local_uname, uo, &pos))
- {
- CloseAccount(fd);
- DosFreeSeg(sel);
- UNLOCKDBFILE();
- return err;
- }
- UserExpand (u, &uo->uo_record);
-
- /* we will allow setting fields on expired accounts */
-
- old_priv = u->user.uc0_priv;
-
- switch (parmnum)
- {
- case U1_ALL:
- new_priv = ((struct user_info_1 far *)buf)->usri1_priv;
- if ((old_priv == USER_PRIV_ADMIN) &&
- (new_priv != USER_PRIV_ADMIN) && last_admin)
- {
- err = NERR_LastAdmin;
- break;
- }
-
- u->user.uc0_priv = new_priv;
-
- flags = ((struct user_info_1 far *)buf)->usri1_flags;
- if ( !(flags & UF_SCRIPT) ||
- ((flags & ~UF_SETTABLE_BITS) != 0) )
- {
- err = ERROR_INVALID_PARAMETER;
- break;
- }
- if (!(u->flags & UF_ACCOUNTDISABLE) &&
- (old_priv == USER_PRIV_ADMIN) &&
- (flags & UF_ACCOUNTDISABLE) && last_admin)
- {
- err = NERR_LastAdmin;
- break;
- }
-
- u->flags = flags;
-
- /* guest accounts can't have operator rights */
- if ( (user->usri1_priv == USER_PRIV_GUEST) &&
- (u->user.uc0_auth_flags) )
- {
- err = ERROR_INVALID_PARAMETER;
- break;
- }
-
-
- if (level == LEVEL_1)
- {
- memcpyf(usr_passwd,
- ((struct user_info_1 far *)buf)->usri1_password,
- ENCRYPTED_PWLEN);
- home = ((struct user_info_1 far *)buf)->usri1_home_dir;
- rem = ((struct user_info_1 far *)buf)->usri1_comment;
- script =
- ((struct user_info_1 far *)buf)->usri1_script_path;
- }
- else if ((level == LEVEL_2) || (level == LEVEL_200)) /* @f08c */
- {
- memcpyf(usr_passwd,
- ((struct user_info_2 far *)buf)->usri2_password,
- ENCRYPTED_PWLEN);
- home = ((struct user_info_2 far *)buf)->usri2_home_dir;
- rem = ((struct user_info_2 far *)buf)->usri2_comment;
- script =
- ((struct user_info_2 far *)buf)->usri2_script_path;
- /* explicitly level 2 stuff */
- if (usr2->usri2_usr_comment != NULL)
- strcpyf(u->usr_comment, usr2->usri2_usr_comment);
- if (usr2->usri2_parms != NULL)
- strcpyf(u->parms, usr2->usri2_parms);
- if (usr2->usri2_full_name != NULL)
- strcpyf(u->full_name, usr2->usri2_full_name);
- u->acct_expires = usr2->usri2_acct_expires;
- u->last_logon = usr2->usri2_last_logon; /* @d01a */
- u->last_logoff = usr2->usri2_last_logoff; /* @d01a */
- u->max_storage = usr2->usri2_max_storage;
- if (usr2->usri2_logon_hours != NULL)
- memcpyf(u->logonhrs, usr2->usri2_logon_hours,
- UNITS_PER_WEEK/8);
- /* workstation list handling Postponed */
- if (usr2->usri2_workstations != NULL)
- {
- if (I_NetListCanonicalize(NULL,
- usr2->usri2_workstations,
- LIST_DELIMITER_STR_API,
- u->workstation,
- sizeof(u->workstation),
- &count,
- NULL,
- 0,
- NAMETYPE_COMPUTER|
- OUTLIST_TYPE_API|
- INLC_FLAGS_CANONICALIZE) ||
- (count > MAXWORKSTATIONS))
- {
- err = ERROR_INVALID_PARAMETER;
- break;
- }
- }
- /* set logon server */
- /* Note that logon_server == NULL will leave present
- * value of this field unchanged. logon_server name is
- * expected and is stored in the form \\logonserver
- */
- if (usr2->usri2_logon_server != NULL)
- {
- type = 0;
- if (usr2->usri2_logon_server[0] == '\0')
- u->logon_server[0] = '\0';
- else if (I_NetPathCanonicalize( NULL,
- usr2->usri2_logon_server,
- u->logon_server,
- UNCLEN+1,
- NULL, &type, 0L) ||
- ((type != ITYPE_UNC_WC) && (type != ITYPE_UNC_COMPNAME)))
- {
- err = ERROR_INVALID_PARAMETER;
- break;
- }
- }
-
- u->country_code = usr2->usri2_country_code;
- u->code_page = usr2->usri2_code_page;
- u->user.uc0_auth_flags = usr2->usri2_auth_flags;
-
- /* set serial number to one provided if level == 200 */ /* @f08a */
- /* and serial given is different than old one. */ /* @f08a */
- if ((level == LEVEL_200) && /* @f08a */
- (u->user.uc0_guid.guid_serial != /* @f08a */
- ((struct user_info_200 far *)buf)->usri200_serial)) /* @f08a */
- { /* @f08a */
- u->user.uc0_guid.guid_serial = /* @f08a */
- ((struct user_info_200 far *)buf)->usri200_serial; /* @f08a */
- full = FULL_USE_SERIAL; /* @f08a */
- } /* @f08a */
- }
- /*
- * Following is common path for all levels
- *
- * Warning: Note that FLAGs have been just set to new value
- * We will use new values
- * allow zerolength password if notreqd bit Set
- * bypass password checks for LM1.0/1.1 clients
- */
-
- if (passlen != IGNORE_PASSWDLEN) /* Not lm1.0 case */
- {
- if (u->flags & UF_PASSWD_NOTREQD)
- {
- if ((passlen != 0) && passlen < Ucb->hdr.min_passwd_len)
- {
- err = NERR_PasswordTooShort;
- break;
- }
- }
- else if (passlen < Ucb->hdr.min_passwd_len)
- {
- err = NERR_PasswordTooShort;
- break;
- }
- } /* end lm1.0 case */
-
- /*
- * check password update restrictions and save the
- * current password for history checking
- */
- if (err = UpdatePassword(u->user.uc0_guid.guid_uid, usr_passwd,
- u->passwd, u->old_passwds, &u->last))
- break;
-
- if (home != NULL) { /* @P01A */
- if (err = SetHomeDir(u->flags, home, u->directory, sizeof(u->directory)))
- break;
- } /* @P01A */
- /*
- * replace the old "super" group membership
- * Unmark old membership first.
- */
- if (old_priv == USER_PRIV_ADMIN)
- MARKOFF(u->user.uc0_groups, Ucb->AdminsId);
- else if (old_priv == USER_PRIV_GUEST)
- MARKOFF(u->user.uc0_groups, Ucb->GuestsId);
- else if (old_priv == USER_PRIV_USER)
- MARKOFF(u->user.uc0_groups, Ucb->UsersId);
-
- if (u->user.uc0_priv == USER_PRIV_ADMIN)
- MARKUSE(u->user.uc0_groups, Ucb->AdminsId);
- else if (u->user.uc0_priv == USER_PRIV_GUEST)
- MARKUSE(u->user.uc0_groups, Ucb->GuestsId);
- else if (u->user.uc0_priv == USER_PRIV_USER)
- MARKUSE(u->user.uc0_groups, Ucb->UsersId);
-
- if (rem != NULL)
- strcpyf(u->comment, rem);
-
- if (script != NULL) { /* @P01A */
- err = SetScriptPath(script, u->script, sizeof(u->script));
- } /* @P01A */
- break;
-
- case U1_PASSWD:
- /*
- * Warning: PASSWD_CANT_CHG not checked since its admin only
- * Allow zerolength password if passwd_notreqd bit set
- * bypass passlen checks for lm1.0 clients
- */
- if (passlen != IGNORE_PASSWDLEN)
- {
- if (u->flags & UF_PASSWD_NOTREQD)
- {
- if ((passlen != 0) && passlen < Ucb->hdr.min_passwd_len)
- {
- err = NERR_PasswordTooShort;
- break;
- }
- }
- else if (passlen < Ucb->hdr.min_passwd_len)
- {
- err = NERR_PasswordTooShort;
- break;
- }
- } /* end lm1.0 case */
- err = UpdatePassword(u->user.uc0_guid.guid_uid, buf,
- u->passwd, u->old_passwds, &u->last);
- break;
-
- case U1_PRIV:
- /* can not change priv of last admin account */
- new_priv = *(unsigned short far *)buf;
- if ( (new_priv != USER_PRIV_USER) &&
- (new_priv != USER_PRIV_ADMIN) &&
- (new_priv != USER_PRIV_GUEST) )
- {
- err = ERROR_INVALID_PARAMETER;
- break;
- }
- if ((old_priv == USER_PRIV_ADMIN) &&
- (new_priv != USER_PRIV_ADMIN) && last_admin)
- {
- err = NERR_LastAdmin;
- break;
- }
- if (new_priv > USER_PRIV_MAX)
- err = ERROR_INVALID_PARAMETER;
- else if (new_priv == USER_PRIV_GUEST && u->user.uc0_auth_flags)
- err = ERROR_INVALID_PARAMETER;
- else
- {
- u->user.uc0_priv = new_priv;
-
- /* Unmark old membership */
- if (old_priv == USER_PRIV_ADMIN)
- MARKOFF(u->user.uc0_groups, Ucb->AdminsId);
- else if (old_priv == USER_PRIV_GUEST)
- MARKOFF(u->user.uc0_groups, Ucb->GuestsId);
- else if (old_priv == USER_PRIV_USER)
- MARKOFF(u->user.uc0_groups, Ucb->UsersId);
-
- /* mark new membership */
- if (u->user.uc0_priv == USER_PRIV_ADMIN)
- MARKUSE(u->user.uc0_groups, Ucb->AdminsId);
- else if (u->user.uc0_priv == USER_PRIV_GUEST)
- MARKUSE(u->user.uc0_groups, Ucb->GuestsId);
- else if (u->user.uc0_priv == USER_PRIV_USER)
- MARKUSE(u->user.uc0_groups, Ucb->UsersId);
- }
- break;
-
- case U1_DIR:
-
- err = SetHomeDir(u->flags, buf, u->directory, sizeof(u->directory));
- break;
-
- case U1_COMMENT:
- err = vcopy(u->comment, buf, sizeof(u->comment));
- break;
-
- case U1_USER_FLAGS:
-
- flags = *((unsigned short far *)buf);
- if ( !(flags & UF_SCRIPT) ||
- ((flags & ~UF_SETTABLE_BITS) != 0) )
- err = ERROR_INVALID_PARAMETER;
- else if (!(u->flags & UF_ACCOUNTDISABLE) &&
- (old_priv == USER_PRIV_ADMIN) &&
- (flags & UF_ACCOUNTDISABLE) && last_admin )
- err = NERR_LastAdmin;
-
- if (!err)
- u->flags = flags;
- break;
-
- case U1_SCRIPT_PATH:
-
- err = SetScriptPath(buf, u->script, sizeof(u->script));
- break;
-
- case PARMNUM_USR_COMMENT:
- err = vcopy(u->usr_comment, buf, sizeof(u->usr_comment));
- break;
-
- case PARMNUM_PARMS:
- err = vcopy(u->parms, buf, sizeof(u->parms));
- break;
-
- case PARMNUM_FULL_NAME:
- /* should we also check the full name for valid characters */
- err = vcopy(u->full_name, buf, sizeof(u->full_name));
- break;
-
- case PARMNUM_WORKSTATIONS:
- if (I_NetListCanonicalize(NULL,
- buf,
- LIST_DELIMITER_STR_API,
- u->workstation,
- sizeof(u->workstation),
- &count,
- NULL, 0,
- NAMETYPE_COMPUTER|OUTLIST_TYPE_API|
- INLC_FLAGS_CANONICALIZE) ||
- (count > MAXWORKSTATIONS))
- err = ERROR_INVALID_PARAMETER;
- break;
-
- case PARMNUM_ACCT_EXPIRES:
- u->acct_expires = *(long far *)buf;
- break;
-
- case PARMNUM_MAX_STORAGE:
- u->max_storage = *(long far *)buf;
- break;
-
- case PARMNUM_LOGON_HOURS:
- memcpyf(u->logonhrs, buf, sizeof(u->logonhrs));
- break;
-
- case PARMNUM_LOGON_SERVER:
- type = 0;
- if (buf[0] == '\0')
- u->logon_server[0] = '\0';
- else if (I_NetPathCanonicalize( NULL,
- buf,
- u->logon_server, UNCLEN+1,
- NULL, &type, 0L) ||
- ((type != ITYPE_UNC_WC) &&
- (type != ITYPE_UNC_COMPNAME)))
- err = ERROR_INVALID_PARAMETER;
- break;
-
- case PARMNUM_COUNTRY_CODE:
- u->country_code = *((unsigned short far *)buf);
- break;
-
- case PARMNUM_AUTH_FLAGS:
- if ((*((unsigned short far *)buf) & ~(AF_SETTABLE_BITS)) != 0)
- err = ERROR_INVALID_PARAMETER;
- else if (old_priv == USER_PRIV_GUEST)
- err = ERROR_INVALID_PARAMETER;
- else
- u->user.uc0_auth_flags = *(unsigned long far *)buf;
- break;
-
- case PARMNUM_LAST_LOGON:
- u->last_logon = *(long far *)buf;
- break;
-
- case PARMNUM_LAST_LOGOFF:
- u->last_logoff = *(long far *)buf;
- break;
-
- case PARMNUM_BADPW_COUNT:
- u->bad_pw_count = *(unsigned short far *)buf;
- break;
-
- case PARMNUM_NUM_LOGONS:
- u->num_logons = *(unsigned short far *)buf;
- break;
-
- case PARMNUM_CODE_PAGE:
- u->code_page = *(unsigned short far *)buf;
- break;
-
- case PARMNUM_PASSWD_EXPIRED:
- if ((int *)*buf)
- u->last = 0L;
- else /* only reset the time if we marked it expired */
- if (!u->last)
- u->last = time_now();
- break;
- default:
- err = ERROR_INVALID_PARAMETER;
- }
-
- if (! err)
- {
- UserCompress (&uo->uo_record, u);
- if (err = WriteUserObject (fd, &pos, uo, full)) /* @f08c */
- ;
- else
- {
- LOCKUSEG();
- if (user1 = FindUidInCache(u->user.uc0_guid.guid_uid,
- u->user.uc0_guid.guid_serial))
- {
- /* update account privs and operator rights */
- user1->uc0_priv = u->user.uc0_priv;
- user1->uc0_auth_flags = u->user.uc0_auth_flags;
- /* copy new group bitmap */
- memcpyf(user1->uc0_groups, u->user.uc0_groups, MAXGROUP/8);
-
- /* LM20 server looks in UAS cache for priv info */
- KickPinballSem();
- }
- UNLOCKUSEG();
- }
- }
-
- UNLOCKDBFILE();
- DosFreeSeg(sel);
- CloseAccount(fd);
- return err;
- #else
- return ERROR_NOT_SUPPORTED;
- #endif /* REMONLY */
-
- /* quiet the compiler */
- if (uname || buf || parmnum || rootdir || level || passlen || last_admin)
- ;
- }
-
- /*
- * UserDel -- Delete a named user
- *
- * Input:
- * uname username
- * last_admin if set implies that there is only 1 admin left
- * Returns:
- *
- * 0 -- success
- * NERR_UserNotFound
- * NERR_ACFFileIOFail
- */
- int
- UserDel(uname, last_admin)
- char far *uname;
- unsigned short last_admin;
- {
- #ifndef REMONLY
- int fd;
- int err = 0; /* assume no error */
- struct user_object far *uo;
- SEL sel;
- unsigned short eread;
- unsigned short etotal;
- unsigned short size;
- struct session_info_10 far * sessinfo;
- char tmp[UNCLEN+1];
- long pos;
- struct user_cache_0 far *user;
- char local_uname[UNLEN+1];
-
- if (err = I_NetNameCanonicalize(NULL, uname, (char far *)local_uname,
- sizeof(local_uname), NAMETYPE_USER, 0L))
- return NERR_UserNotFound;
-
- if (err = OpenAccount(&fd))
- return err;
- if (err = DosAllocSeg(MAX_USER_SIZE, &sel, 0))
- {
- CloseAccount(fd);
- return err;
- }
- else
- uo = (struct user_object far *) PTR(sel, 0);
-
- LOCKDBFILE();
-
- if (err = GetUserObject (fd, local_uname, uo, &pos))
- ; /* name not found */
-
- else if (((uo->uo_record.user.uc0_priv & USER_PRIV_MASK) == USER_PRIV_ADMIN) && !(uo->uo_record.flags & UF_ACCOUNTDISABLE) && last_admin)
- err = NERR_LastAdmin;
-
- else if (AccessRemoveId(uo->uo_record.user.uc0_guid.guid_uid,
- uo->uo_record.user.uc0_guid.guid_serial))
- err = NERR_ACFFileIOFail;
- else {
- /* purge this users record from the cache */
- if (DeleteUserObject(fd, pos, uo) != 0)
- err = NERR_ACFFileIOFail;
- else {
- LOCKUSEG();
- if (user = FindUidInCache(
- uo->uo_record.user.uc0_guid.guid_uid,
- uo->uo_record.user.uc0_guid.guid_serial))
- {
- PurgeUserRecord(user);
- }
-
- Ucb->usercnt --; /* Update counter */
- KickPinballSem();
- UNLOCKUSEG();
- }
- }
- if (fd >=0 )
- CloseAccount(fd);
- DosFreeSeg(sel);
- UNLOCKDBFILE();
-
- if (err)
- return err;
-
- /* Tell any netlogon service that is around about this user
- * being deleted so that the logon tables can be updated. This
- * function lives in api\ssi\ssiutil.c. It's a side affect
- * so we don't care about errors.
- */
-
- FreeUserEntries(local_uname);
-
- /* quit if server is not running */
- if (GetServerSegs())
- return NERR_Success;
- else
- FreeServerSegs();
-
- /*
- * All sessions belonging to this user are deleted.
- * Note that we map evry error to InternalError since we
- * have already deleted the user's record in the database and
- * removed him from the cache.
- *
- * Warning: if you try to delete your own account on a remote
- * server, provided you have privs to do that, your
- * session will be deleted and most likely you will
- * get VC_DISCONNECTED error from redir since the
- * transaction never got completed.
- */
- err = NetSessionEnum(NULL, 10, NULL, 0, &eread, &etotal);
- if (err == NERR_BufTooSmall || err == ERROR_MORE_DATA || err == 0)
- {
- if (etotal == 0)
- return NERR_Success;
- /* get the worst case size estimate */
- size = sizeof(struct session_info_10) + (UNLEN+1) + (CNLEN+1);
- size *= etotal;
- if (err = DosAllocSeg(size, &sel, 0))
- return NERR_InternalError;
- else
- sessinfo = (struct session_info_10 far *) PTR(sel, 0);
- }
- if (NetSessionEnum(NULL, 10, (char far *) sessinfo, size, &eread, &etotal))
- {
- DosFreeSeg(sel);
- return NERR_InternalError;
- }
- /* walk through the buffer looking for name of this user */
- while (etotal --)
- {
- if (!I_NetNameCompare(NULL, local_uname, sessinfo->sesi10_username,
- NAMETYPE_USER, 0L))
- {
- strcpyf(tmp, "\\\\");
- strcatf(tmp, sessinfo->sesi10_cname);
- if (WSessionDel(NULL, tmp, 0, NULL, ACCESS_LOCAL))
- break;
- }
- sessinfo++;
- }
-
- DosFreeSeg(sel);
- return err;
- #else
- return ERROR_NOT_SUPPORTED;
- #endif /* REMONLY */
-
- /* quiet the compiler */
- if (uname || last_admin);
- }
-
-
- /*
- * Vcopy -- Verify the length and copy
- */
- static int near
- vcopy(to, from, size)
- char far *to;
- char far *from;
- int size;
- {
- int len;
-
- if ((len = strlenf(from) ) >= size)
- return ERROR_INVALID_PARAMETER;
- memcpyf(to, from, len+1);
- return 0;
- }
-
-
- /**** UserGetModals
- *
- * Purpose: Get global User Modals
- *
- * Entry: level level of details requested (MBZ for LM1.2)
- * buf buffer to return data in
- * buflen size of buffer must be at least sizeof struct
- * total total bytes available
- *
- * Exit: buffer filled with struct user_modals_info_0
- *
- * Return: NERR_Success or OS/2 error as appropriate
- *
- * NOTE: This function will succeed even though UAS may not be
- * running but a good access database (net.acc) exists.
- *
- */
- int
- UserGetModals(level, buf, buflen, total)
- short level;
- char far * buf;
- unsigned short buflen;
- unsigned short far * total;
- {
- #ifndef REMONLY
- int fd = 0; // Jay Fix for SA
- int errfd = 0 ; // Jay Fix for SA
- int err = 0;
- long pos;
- unsigned short bytesread;
- char far * end;
- char hdrbuf[sizeof(struct _ahdr)];
- struct user_modals_info_0 far *m;
- struct user_modals_info_1 far *p;
- struct user_modals_info_101 far *p1;
- struct _ahdr far *h;
-
- end = buf + buflen;
-
- if (Ucb == NULL)
- errfd = OpenAccountSpecial(&fd);
- else
- errfd = OpenAccount(&fd);
-
- if (errfd == NERR_Success)
- {
-
- if (Ucb != NULL)
- LOCKDBFILE();
-
- if ((err = DosChgFilePtr(fd, 0L, 0, &pos)))
- ;
- else if ((err = DosRead(fd, hdrbuf, sizeof(struct _ahdr),
- &bytesread)) || bytesread != sizeof(struct _ahdr))
- err = err ? err : NERR_ACFFileIOFail;
- else
- h = (struct _ahdr far *) hdrbuf;
-
- if (Ucb != NULL)
- UNLOCKDBFILE();
-
- }
-
- else // Jay Fix for SA
- return errfd; // Jay Fix for SA
-
- if (err)
- {
- CloseAccount(fd);
- return err;
- }
-
- if (level == LEVEL_0)
- {
- m = (struct user_modals_info_0 far *)buf;
- *total = sizeof(struct user_modals_info_0);
- if (buflen < sizeof(struct user_modals_info_0))
- {
- CloseAccount(fd);
- return NERR_BufTooSmall;
- }
- m->usrmod0_min_passwd_len = h->min_passwd_len;
- m->usrmod0_max_passwd_age = h->max_passwd_age;
- m->usrmod0_min_passwd_age = h->min_passwd_age;
- m->usrmod0_force_logoff = h->force_logoff;
- m->usrmod0_password_hist_len = h->passwd_hist_len;
- m->usrmod0_maxbadpw = h->max_bad_passwd;
- }
- else if (level == LEVEL_1)
- {
- *total = sizeof(struct user_modals_info_1) +
- strlenf(h->primary.uas0_computer) + 1;
- if (buflen < sizeof(struct user_modals_info_1))
- {
- CloseAccount(fd);
- return NERR_BufTooSmall;
- }
- p = (struct user_modals_info_1 far *)buf;
- p->usrmod1_role = h->role;
- p->usrmod1_primary = h->primary.uas0_computer;
- NetPackString(&p->usrmod1_primary, (char far *)(p+1), &end);
- if (*total > buflen)
- err = ERROR_MORE_DATA;
- }
- else if (level == LEVEL_100)
- {
- *total = sizeof(struct user_modals_info_100);
- if (buflen < sizeof(struct user_modals_info_100))
- {
- CloseAccount(fd);
- return NERR_BufTooSmall;
- }
- memcpyf(((struct user_modals_info_100 far *)buf)->usrmod100_DBIdInfo,
- h->DBIdInfo, DBIDINFO_SIZE);
- }
- else if (level == LEVEL_101)
- {
- *total = sizeof(struct user_modals_info_101) +
- strlenf(h->local.uas0_computer) + 1 +
- strlenf(h->primary.uas0_computer) + 1;
- if (buflen < sizeof(struct user_modals_info_101))
- {
- CloseAccount(fd);
- return NERR_BufTooSmall;
- }
- p1 = (struct user_modals_info_101 far *)buf;
- p1->usrmod101_local_date = h->local.uas0_time_created;
- p1->usrmod101_local_counter = h->local.uas0_serial_number;
- p1->usrmod101_primary_date = h->primary.uas0_time_created;
- p1->usrmod101_primary_counter = h->primary.uas0_serial_number;
- p1->usrmod101_local_computer = h->local.uas0_computer;
- NetPackString(&p1->usrmod101_local_computer,
- (char far *)(p1+1), &end);
- p1->usrmod101_primary_computer = h->primary.uas0_computer;
- NetPackString(&p1->usrmod101_primary_computer,
- (char far *)(p1+1), &end);
- if (*total > buflen)
- err = ERROR_MORE_DATA;
- }
-
- CloseAccount(fd);
- return err;
- #else
- return ERROR_NOT_SUPPORTED;
- #endif /* REMONLY */
-
- /* quiet the compiler */
- if (level || buf || buflen || total);
- }
-
-
- /**** UserSetModals
- *
- * Purpose: Set global User Modals
- *
- * Entry: level level of details requested (MBZ for LM1.2)
- * buf filled with struct user_modals_info_0
- * buflen size of buffer
- * parmnum ordinal number of parameter to set
- *
- * Exit: appropriate fields in net.acc and cache (conditional)
- * modified
- *
- * Return: NERR_Success or OS/2 error as appropriate
- *
- * NOTE: This function will succeed at level 0 even though UAS may
- * not be running but a good access database (net.acc) exists.
- *
- */
- int
- UserSetModals(level, buf, buflen, parmnum)
- short level;
- char far * buf;
- unsigned short buflen;
- short parmnum;
- {
- #ifndef REMONLY
- int err, fd;
- long new;
- unsigned short written;
- unsigned short bytesread;
- unsigned short role;
- struct user_modals_info_0 far *m;
- char far * primary;
- struct _ahdr far *p;
- char hdrbuf[sizeof(struct _ahdr)];
- char tmpbuf[CNLEN+1];
-
- if (Ucb == NULL)
- err = OpenAccountSpecial(&fd);
- else
- err = OpenAccount(&fd);
-
- if (err == NERR_Success)
- {
-
- if (Ucb != NULL)
- LOCKDBFILE();
-
- if ((err = DosChgFilePtr(fd, 0L, 0, &new)))
- ;
- else if ((err = DosRead(fd, hdrbuf, sizeof(struct _ahdr),
- &bytesread)) || bytesread != sizeof(struct _ahdr))
- err = err ? err : NERR_ACFFileIOFail;
- else
- p = (struct _ahdr far *) hdrbuf;
-
- if (Ucb != NULL)
- UNLOCKDBFILE();
- }
- if (err)
- {
- CloseAccount(fd);
- return err;
- }
-
- if (Ucb != NULL)
- LOCKDBFILE();
- if (level == LEVEL_0)
- {
- switch(parmnum)
- {
- case MODAL0_PARMNUM_ALL:
- m = (struct user_modals_info_0 far *)buf;
- // if (m->usrmod0_min_passwd_len < 0 ||
- if (m->usrmod0_min_passwd_len > PWLEN)
- {
- err = ERROR_INVALID_PARAMETER;
- break;
- }
- else
- p->min_passwd_len = m->usrmod0_min_passwd_len;
- if ((m->usrmod0_max_passwd_age < ONE_DAY) ||
- (m->usrmod0_max_passwd_age < m->usrmod0_min_passwd_age))
- {
- err = ERROR_INVALID_PARAMETER;
- break;
- }
- p->max_bad_passwd = m->usrmod0_maxbadpw;
- p->max_passwd_age = m->usrmod0_max_passwd_age;
- p->min_passwd_age = m->usrmod0_min_passwd_age;
- p->force_logoff = m->usrmod0_force_logoff;
- // if (m->usrmod0_password_hist_len < 0 ||
- if (m->usrmod0_password_hist_len > DEF_MAX_PWHIST)
- err = ERROR_INVALID_PARAMETER;
- else
- p->passwd_hist_len = m->usrmod0_password_hist_len;
- break;
- case MODAL0_PARMNUM_MIN_LEN:
- // if (*(unsigned short far *)buf < 0 ||
- if (*(unsigned short far *)buf > PWLEN)
- err = ERROR_INVALID_PARAMETER;
- else
- p->min_passwd_len = *(unsigned short far *)buf;
- break;
- case MODAL0_PARMNUM_MAX_AGE:
- if ((p->min_passwd_age > *(unsigned long far *)buf) ||
- (*(unsigned long far *)buf < ONE_DAY))
- err = ERROR_INVALID_PARAMETER;
- else
- p->max_passwd_age = *(unsigned long far *)buf;
- break;
- case MODAL0_PARMNUM_MIN_AGE:
- if (p->max_passwd_age < *(unsigned long far *)buf)
- err = ERROR_INVALID_PARAMETER;
- else
- p->min_passwd_age = *(unsigned long far *)buf;
- break;
- case MODAL0_PARMNUM_FORCEOFF:
- p->force_logoff = *(unsigned long far *)buf;
- break;
- case MODAL0_PARMNUM_HISTLEN:
- // if (*(unsigned short far *)buf < 0 ||
- if (*(unsigned short far *)buf > DEF_MAX_PWHIST)
- err = ERROR_INVALID_PARAMETER;
- else
- p->passwd_hist_len = *(unsigned short far *)buf;
- break;
- case MODAL0_PARMNUM_MAX_BADPW:
- p->max_bad_passwd = *(unsigned short far *)buf;
- break;
- default:
- err = ERROR_INVALID_PARAMETER;
- }
- }
- else if (level == LEVEL_1)
- {
- if (parmnum == MODAL1_PARMNUM_ALL)
- {
- primary = ((struct user_modals_info_1 far *)buf)->usrmod1_primary;
- role = ((struct user_modals_info_1 far *)buf)->usrmod1_role;
- }
- else if (parmnum == MODAL1_PARMNUM_PRIMARY)
- primary = buf;
- else if (parmnum == MODAL1_PARMNUM_ROLE)
- role = *(unsigned short far *)buf;
-
- if (parmnum == MODAL1_PARMNUM_ALL || parmnum == MODAL1_PARMNUM_ROLE)
- {
- if ((role != UAS_ROLE_PRIMARY) &&
- (role != UAS_ROLE_MEMBER) &&
- (role != UAS_ROLE_BACKUP) &&
- (role != UAS_ROLE_STANDALONE))
- err = ERROR_INVALID_PARAMETER;
- else
- p->role = role;
- }
- if (parmnum == MODAL1_PARMNUM_ALL || parmnum == MODAL1_PARMNUM_PRIMARY)
- {
- if (primary == NULL)
- ;
- else if (primary[0] == '\0')
- p->primary.uas0_computer[0] = '\0';
- else
- {
- if (I_NetNameCanonicalize(NULL,
- primary,
- tmpbuf, /* output buffer */
- CNLEN+1, /* sizeof output buf */
- NAMETYPE_COMPUTER,
- 0L))
- err = ERROR_INVALID_PARAMETER;
- else
- strcpyf(p->primary.uas0_computer, tmpbuf);
- }
- }
- }
- else if (level == LEVEL_100)
- {
- memcpyf(p->DBIdInfo,
- ((struct user_modals_info_100 far *)buf)->usrmod100_DBIdInfo,
- DBIDINFO_SIZE);
- }
- else if (level == LEVEL_101)
- {
- /* WARNING: special case for internal use, see uasuser.c */
- p->local.uas0_time_created =
- ((struct user_modals_info_101 far *)buf)->usrmod101_local_date;
- p->local.uas0_serial_number =
- ((struct user_modals_info_101 far *)buf)->usrmod101_local_counter;
- p->primary.uas0_time_created =
- ((struct user_modals_info_101 far *)buf)->usrmod101_primary_date;
- p->primary.uas0_serial_number =
- ((struct user_modals_info_101 far *)buf)->usrmod101_primary_counter;
-
- /* NULL primary name means the caller does not want to
- * change the primary. It is the responsibility of the
- * caller to make that decision.
- */
- if ( ( ((struct user_modals_info_101 far *)buf)->usrmod101_primary_computer) != NULL) /*d9983*/
- strcpyf(p->primary.uas0_computer, /*d9983*/
- ((struct user_modals_info_101 far *)buf)->usrmod101_primary_computer ); /*d9983*/
- }
-
- /* Update disk record: update cache if disk update OK */
- if (err == NERR_Success)
- {
- if (!(err = DosChgFilePtr(fd, 0L, 0, &new)))
- err = DosWrite(fd, (char far *) hdrbuf, sizeof(struct _ahdr), &written);
-
- if (err || (written != sizeof(struct _ahdr)))
- err = err ? err : NERR_ACFFileIOFail;
- }
-
- if (Ucb != NULL && err == NERR_Success)
- {
- /* copy the new information in cache if UAS running */
- LOCKUSEG();
- if (level == LEVEL_0)
- {
- switch(parmnum)
- {
- case MODAL0_PARMNUM_ALL:
- memcpyf((char far *) &Ucb->hdr, (char far *)p, sizeof(struct _ahdr));
- break;
- case MODAL0_PARMNUM_MIN_LEN:
- Ucb->hdr.min_passwd_len = p->min_passwd_len;
- break;
- case MODAL0_PARMNUM_MAX_AGE:
- Ucb->hdr.max_passwd_age = p->max_passwd_age;
- break;
- case MODAL0_PARMNUM_MIN_AGE:
- Ucb->hdr.min_passwd_age = p->min_passwd_age;
- break;
- case MODAL0_PARMNUM_FORCEOFF:
- Ucb->hdr.force_logoff = p->force_logoff;
- break;
- case MODAL0_PARMNUM_HISTLEN:
- Ucb->hdr.passwd_hist_len = p->passwd_hist_len;
- break;
- case MODAL0_PARMNUM_MAX_BADPW:
- Ucb->hdr.max_bad_passwd = p->max_bad_passwd;
- break;
- }
- }
- else if (level == LEVEL_1)
- {
- Ucb->hdr.role = p->role;
- strcpyf(Ucb->hdr.primary.uas0_computer, p->primary.uas0_computer);
- if (Ucb->hdr.role == UAS_ROLE_PRIMARY || Ucb->hdr.role == UAS_ROLE_STANDALONE)
- Ucb->UpdatesOK = TRUE;
- else
- Ucb->UpdatesOK = FALSE;
- }
- else if (level == LEVEL_100)
- memcpyf(Ucb->hdr.DBIdInfo, p->DBIdInfo, DBIDINFO_SIZE);
- else if (level == LEVEL_101)
- {
- /* WARNING: special case for internal use, see uasuser.c */
- Ucb->hdr.local.uas0_time_created = p->local.uas0_time_created;
- Ucb->hdr.local.uas0_serial_number = p->local.uas0_serial_number;
- Ucb->hdr.primary.uas0_time_created = p->primary.uas0_time_created;
- Ucb->hdr.primary.uas0_serial_number = p->primary.uas0_serial_number;
- }
-
- UNLOCKUSEG();
- }
-
- CloseAccount(fd);
- if (Ucb != NULL)
- UNLOCKDBFILE();
- return err;
- #else
- return ERROR_NOT_SUPPORTED;
- #endif /* REMONLY */
-
- /* quiet the compiler */
- if (level || buf || buflen || parmnum)
- ;
- }
-
-
- #ifdef LOCKOUT
- /*
- * TrackBadPasswords
- * The purpose of this function is to bump the bad_pw_count
- * field in user's record and disable his account (lock out)
- * if bad password attempts have exceeded beyond the limit
- * specified by reserved1 modal. If the password matched
- * correctly and account was still enabled i.e. not locked
- * out, bad password count will be reset to 0. Bad password
- * tries are counted even though the account may have been
- * locked out. Note that last Admin account will never be
- * locked out.
- *
- * Entry:
- * u struct _userrec far *
- * fd file handle of UAS database
- *
- * Exit:
- *
- *
- */
- void
- TrackBadPasswords(passwd_match, fd, u, wkstn)
- int passwd_match;
- int fd;
- struct _userrec far *u;
- char far * wkstn;
- {
- unsigned short err = 0;
- unsigned short dummy;
- unsigned short total;
- unsigned short last_admin = FALSE;
-
- if (passwd_match)
- {
- if (u->flags & UF_ACCOUNTDISABLE)
- return;
- else
- u->bad_pw_count = 0;
- }
- else
- {
- (u->bad_pw_count)++;
- /* disable the account if we exceed reserved1 and it's active*/
- if (!(u->flags & UF_ACCOUNTDISABLE))
- {
- if (u->bad_pw_count > Ucb->hdr.reserved1)
- {
- /* do not disable the last Admin account */
- if ((u->user.uc0_priv & USER_PRIV_MASK) == USER_PRIV_ADMIN)
- {
- if (!IsLastActiveUser(u->name, ADMINGROUP, &total))
- u->flags |= UF_ACCOUNTDISABLE;
- }
- }
- }
- }
- /* update the bad_pw_count field reset or bump as the case maybe */
- WriteUserRec(fd, &u->user, TRUE);
- audit_alert_lockout(last_admin, u->name, wkstn);
- }
- #endif /* LOCKOUT */
-
-
-
-
- /*
- * SetHomeDir
- *
- * Purpose: Set the user's home directory field in the user
- * record if all the neccessary requirement are met.
- *
- *
- * Notes:
- * If the user's account has UF_HOMEDIR_REQD flag set
- * then a valid absolute path (local or unc) must be
- * supplied for the home directory field. A null string
- * is not a valid path. In case of NetUserSetInfo with
- * zero parmnum the newly supplied flags are used for
- * verifying the restrictions whereas in case of non zero
- * parmnum the flgas stored in user's account are used.
- *
- * Assumptions:
- * input arguments are presumed to be valid
- *
- */
- unsigned short
- SetHomeDir(user_flags, in_homedir, out_homedir, outlen)
- unsigned short user_flags;
- char far * in_homedir;
- char far * out_homedir;
- unsigned short outlen;
- {
- unsigned long type = 0;
- unsigned short is_homedir_null = FALSE;
-
-
- /*
- * check if home directory is mandated otherwise follow
- * normal course
- */
- if ( (in_homedir == NULL) || (*in_homedir == '\0') )
- is_homedir_null = TRUE;
-
- if ( (user_flags & UF_HOMEDIR_REQUIRED) && (is_homedir_null == TRUE) )
- return ERROR_INVALID_PARAMETER;
-
- if (is_homedir_null)
- {
- out_homedir[0] = '\0';
- return NERR_Success;
- }
-
- if (I_NetPathCanonicalize(NULL,
- in_homedir,
- out_homedir,
- outlen,
- NULL,
- &type,
- 0L))
-
- return ERROR_INVALID_PARAMETER;
-
- if ( (type != ITYPE_PATH_ABSD) && (type != ITYPE_UNC) )
- return ERROR_INVALID_PARAMETER;
-
- return NERR_Success;
- }
-
-
- /*
- * SetScriptPath
- *
- * Purpose: Set the user's script path field in the user
- * record if all the neccessary requirement are met.
- *
- *
- * Notes:
- * Script path must be a relative path
- *
- * Assumptions:
- * input arguments are presumed to be valid
- *
- */
- unsigned short
- SetScriptPath(in_script, out_script, outlen)
- char far * in_script;
- char far * out_script;
- unsigned short outlen;
- {
- unsigned long type = 0;
-
- if ( (in_script == NULL) || (*in_script == '\0') )
- {
- out_script[0] = '\0';
- return NERR_Success;
- }
-
- if(I_NetPathCanonicalize(NULL,
- in_script,
- out_script,
- outlen,
- NULL,
- &type,
- 0L) || (type != ITYPE_PATH_RELND) )
-
- return ERROR_INVALID_PARAMETER;
-
- return NERR_Success;
- }