Print this page
    
NEX-19057 All zfs/nfs/smb threads in door calls to idle idmap
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
NEX-5260 smbd segfaults while running smbtorture:rpc.lsa.lookupnames
NEX-5261 smbd segfaults while running smbtorture:rpc.winreg
NEX-5262 smbd segfaults while running smbtorture:rpc.samba3
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
NEX-2667 Wrong error when join domain with wrong password
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
Reviewed by: Bayard Bell <bayard.bell@nexenta.com>
NEX-2225 Unable to join NexentaStor to 2008 AD
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/lib/smbsrv/libmlsvc/common/lsalib.c
          +++ new/usr/src/lib/smbsrv/libmlsvc/common/lsalib.c
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License (the "License").
   6    6   * You may not use this file except in compliance with the License.
   7    7   *
   8    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9    9   * or http://www.opensolaris.org/os/licensing.
  10   10   * See the License for the specific language governing permissions
  11   11   * and limitations under the License.
  12   12   *
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  
    | 
      ↓ open down ↓ | 
    13 lines elided | 
    
      ↑ open up ↑ | 
  
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  24      - * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
       24 + * Copyright 2019 Nexenta Systems, Inc.  All rights reserved.
  25   25   */
  26   26  
  27   27  /*
  28   28   * This module provides the high level interface to the LSA RPC functions.
  29   29   */
  30   30  
  31   31  #include <strings.h>
  32   32  #include <unistd.h>
  33   33  
  34   34  #include <smbsrv/libsmb.h>
  35   35  #include <smbsrv/libmlsvc.h>
  36   36  #include <smbsrv/smbinfo.h>
  37   37  #include <smbsrv/smb_token.h>
  38   38  
  39   39  #include <lsalib.h>
  40   40  
       41 +static uint32_t lsa_lookup_name_int(char *, uint16_t, smb_account_t *,
       42 +    boolean_t);
       43 +static uint32_t lsa_lookup_sid_int(smb_sid_t *, smb_account_t *, boolean_t);
       44 +
  41   45  static uint32_t lsa_lookup_name_builtin(char *, char *, smb_account_t *);
  42   46  static uint32_t lsa_lookup_name_domain(char *, smb_account_t *);
  43   47  
  44   48  static uint32_t lsa_lookup_sid_builtin(smb_sid_t *, smb_account_t *);
  45   49  static uint32_t lsa_lookup_sid_domain(smb_sid_t *, smb_account_t *);
  46   50  
  47   51  static uint32_t lsa_list_accounts(mlsvc_handle_t *);
  48   52  static uint32_t lsa_map_status(uint32_t);
  49   53  
  50   54  /*
  51   55   * Lookup the given account and returns the account information
  52   56   * in the passed smb_account_t structure.
  53   57   *
  54   58   * The lookup is performed in the following order:
  55   59   *    well known accounts
  56   60   *    local accounts
  57   61   *    domain accounts
  58   62   *
  59   63   * If it's established the given account is well know or local
  60   64   * but the lookup fails for some reason, the next step(s) won't be
  61   65   * performed.
  62   66   *
  63   67   * If the name is a domain account, it may refer to a user, group or
  64   68   * alias. If it is a local account, its type should be specified
  65   69   * in the sid_type parameter. In case the account type is unknown
  66   70   * sid_type should be set to SidTypeUnknown.
  67   71   *
  
    | 
      ↓ open down ↓ | 
    17 lines elided | 
    
      ↑ open up ↑ | 
  
  68   72   * account argument could be either [domain\]name or [domain/]name.
  69   73   *
  70   74   * Return status:
  71   75   *
  72   76   *   NT_STATUS_SUCCESS          Account is successfully translated
  73   77   *   NT_STATUS_NONE_MAPPED      Couldn't translate the account
  74   78   */
  75   79  uint32_t
  76   80  lsa_lookup_name(char *account, uint16_t type, smb_account_t *info)
  77   81  {
       82 +        return (lsa_lookup_name_int(account, type, info, B_TRUE));
       83 +}
       84 +
       85 +/* Variant that avoids the call out to AD. */
       86 +uint32_t
       87 +lsa_lookup_lname(char *account, uint16_t type, smb_account_t *info)
       88 +{
       89 +        return (lsa_lookup_name_int(account, type, info, B_FALSE));
       90 +}
       91 +
       92 +uint32_t
       93 +lsa_lookup_name_int(char *account, uint16_t type, smb_account_t *info,
       94 +    boolean_t try_ad)
       95 +{
  78   96          char nambuf[SMB_USERNAME_MAXLEN];
  79   97          char dombuf[SMB_PI_MAX_DOMAIN];
  80   98          char *name, *domain;
  81   99          uint32_t status;
  82  100          char *slash;
  83  101  
      102 +        if (account == NULL)
      103 +                return (NT_STATUS_NONE_MAPPED);
      104 +
  84  105          (void) strsubst(account, '/', '\\');
  85  106          (void) strcanon(account, "\\");
  86  107          /* \john -> john */
  87  108          account += strspn(account, "\\");
  88  109  
  89  110          if ((slash = strchr(account, '\\')) != NULL) {
  90  111                  *slash = '\0';
  91  112                  (void) strlcpy(dombuf, account, sizeof (dombuf));
  92  113                  (void) strlcpy(nambuf, slash + 1, sizeof (nambuf));
  93  114                  *slash = '\\';
  94  115                  name = nambuf;
  95  116                  domain = dombuf;
  96  117          } else {
  
    | 
      ↓ open down ↓ | 
    3 lines elided | 
    
      ↑ open up ↑ | 
  
  97  118                  name = account;
  98  119                  domain = NULL;
  99  120          }
 100  121  
 101  122          status = lsa_lookup_name_builtin(domain, name, info);
 102  123          if (status == NT_STATUS_NOT_FOUND) {
 103  124                  status = smb_sam_lookup_name(domain, name, type, info);
 104  125                  if (status == NT_STATUS_SUCCESS)
 105  126                          return (status);
 106  127  
 107      -                if ((domain == NULL) || (status == NT_STATUS_NOT_FOUND))
      128 +                if (try_ad && ((domain == NULL) ||
      129 +                    (status == NT_STATUS_NOT_FOUND))) {
 108  130                          status = lsa_lookup_name_domain(account, info);
      131 +                }
 109  132          }
 110  133  
 111  134          return ((status == NT_STATUS_SUCCESS) ? status : NT_STATUS_NONE_MAPPED);
 112  135  }
 113  136  
 114  137  uint32_t
 115  138  lsa_lookup_sid(smb_sid_t *sid, smb_account_t *info)
 116  139  {
      140 +        return (lsa_lookup_sid_int(sid, info, B_TRUE));
      141 +}
      142 +
      143 +/* Variant that avoids the call out to AD. */
      144 +uint32_t
      145 +lsa_lookup_lsid(smb_sid_t *sid, smb_account_t *info)
      146 +{
      147 +        return (lsa_lookup_sid_int(sid, info, B_FALSE));
      148 +}
      149 +
      150 +static uint32_t
      151 +lsa_lookup_sid_int(smb_sid_t *sid, smb_account_t *info, boolean_t try_ad)
      152 +{
 117  153          uint32_t status;
 118  154  
 119  155          if (!smb_sid_isvalid(sid))
 120  156                  return (NT_STATUS_INVALID_SID);
 121  157  
 122  158          status = lsa_lookup_sid_builtin(sid, info);
 123  159          if (status == NT_STATUS_NOT_FOUND) {
 124  160                  status = smb_sam_lookup_sid(sid, info);
 125      -                if (status == NT_STATUS_NOT_FOUND)
      161 +                if (try_ad && status == NT_STATUS_NOT_FOUND) {
 126  162                          status = lsa_lookup_sid_domain(sid, info);
      163 +                }
 127  164          }
 128  165  
 129  166          return ((status == NT_STATUS_SUCCESS) ? status : NT_STATUS_NONE_MAPPED);
 130  167  }
 131  168  
 132  169  /*
 133  170   * Obtains the primary domain SID and name from the specified server
 134  171   * (domain controller).
 135  172   *
 136  173   * The requested information will be returned via 'info' argument.
 137  174   *
 138  175   * Returns NT status codes. (Raw, not LSA-ized)
 139  176   */
 140  177  DWORD
 141  178  lsa_query_primary_domain_info(char *server, char *domain,
 142  179      smb_domain_t *info)
 143  180  {
 144  181          mlsvc_handle_t domain_handle;
 145  182          char user[SMB_USERNAME_MAXLEN];
 146  183          DWORD status;
 147  184  
 148  185          smb_ipc_get_user(user, SMB_USERNAME_MAXLEN);
 149  186  
 150  187          status = lsar_open(server, domain, user, &domain_handle);
 151  188          if (status != 0)
 152  189                  return (status);
 153  190  
 154  191          status = lsar_query_info_policy(&domain_handle,
 155  192              MSLSA_POLICY_PRIMARY_DOMAIN_INFO, info);
 156  193  
 157  194          (void) lsar_close(&domain_handle);
 158  195          return (status);
 159  196  }
 160  197  
 161  198  /*
 162  199   * Obtains the account domain SID and name from the current server
 163  200   * (domain controller).
 164  201   *
 165  202   * The requested information will be returned via 'info' argument.
 166  203   *
 167  204   * Returns NT status codes. (Raw, not LSA-ized)
 168  205   */
 169  206  DWORD
 170  207  lsa_query_account_domain_info(char *server, char *domain,
 171  208      smb_domain_t *info)
 172  209  {
 173  210          mlsvc_handle_t domain_handle;
 174  211          char user[SMB_USERNAME_MAXLEN];
 175  212          DWORD status;
 176  213  
 177  214          smb_ipc_get_user(user, SMB_USERNAME_MAXLEN);
 178  215  
 179  216          status = lsar_open(server, domain, user, &domain_handle);
 180  217          if (status != 0)
 181  218                  return (status);
 182  219  
 183  220          status = lsar_query_info_policy(&domain_handle,
 184  221              MSLSA_POLICY_ACCOUNT_DOMAIN_INFO, info);
 185  222  
 186  223          (void) lsar_close(&domain_handle);
 187  224          return (status);
 188  225  }
 189  226  
 190  227  /*
 191  228   * lsa_query_dns_domain_info
 192  229   *
 193  230   * Obtains the DNS domain info from the specified server
 194  231   * (domain controller).
 195  232   *
 196  233   * The requested information will be returned via 'info' argument.
 197  234   *
 198  235   * Returns NT status codes. (Raw, not LSA-ized)
 199  236   */
 200  237  DWORD
 201  238  lsa_query_dns_domain_info(char *server, char *domain, smb_domain_t *info)
 202  239  {
 203  240          mlsvc_handle_t domain_handle;
 204  241          char user[SMB_USERNAME_MAXLEN];
 205  242          DWORD status;
 206  243  
 207  244          smb_ipc_get_user(user, SMB_USERNAME_MAXLEN);
 208  245  
 209  246          status = lsar_open(server, domain, user, &domain_handle);
 210  247          if (status != 0)
 211  248                  return (status);
 212  249  
 213  250          status = lsar_query_info_policy(&domain_handle,
 214  251              MSLSA_POLICY_DNS_DOMAIN_INFO, info);
 215  252  
 216  253          (void) lsar_close(&domain_handle);
 217  254          return (status);
 218  255  }
 219  256  
 220  257  /*
 221  258   * Enumerate the trusted domains of  primary domain.
 222  259   * This is the basic enumaration call which only returns the
 223  260   * NetBIOS name of the domain and its SID.
 224  261   *
 225  262   * The requested information will be returned via 'info' argument.
 226  263   *
 227  264   * Returns NT status codes.  (Raw, not LSA-ized)
 228  265   */
 229  266  DWORD
 230  267  lsa_enum_trusted_domains(char *server, char *domain,
 231  268      smb_trusted_domains_t *info)
 232  269  {
 233  270          mlsvc_handle_t domain_handle;
 234  271          char user[SMB_USERNAME_MAXLEN];
 235  272          DWORD enum_context;
 236  273          DWORD status;
 237  274  
 238  275          smb_ipc_get_user(user, SMB_USERNAME_MAXLEN);
 239  276  
 240  277          status = lsar_open(server, domain, user, &domain_handle);
 241  278          if (status != 0)
 242  279                  return (status);
 243  280  
 244  281          enum_context = 0;
 245  282  
 246  283          status = lsar_enum_trusted_domains(&domain_handle, &enum_context, info);
 247  284          if (status == NT_STATUS_NO_MORE_ENTRIES) {
 248  285                  /*
 249  286                   * STATUS_NO_MORE_ENTRIES indicates that we
 250  287                   * have all of the available information.
 251  288                   */
 252  289                  status = NT_STATUS_SUCCESS;
 253  290          }
 254  291  
 255  292          (void) lsar_close(&domain_handle);
 256  293          return (status);
 257  294  }
 258  295  
 259  296  /*
 260  297   * Enumerate the trusted domains of the primary domain.
 261  298   * This is the extended enumaration call which besides
 262  299   * NetBIOS name of the domain and its SID, it will return
 263  300   * the FQDN plus some trust information which is not used.
 264  301   *
 265  302   * The requested information will be returned via 'info' argument.
 266  303   *
 267  304   * Returns NT status codes. (Raw, not LSA-ized)
 268  305   */
 269  306  DWORD
 270  307  lsa_enum_trusted_domains_ex(char *server, char *domain,
 271  308      smb_trusted_domains_t *info)
 272  309  {
 273  310          mlsvc_handle_t domain_handle;
 274  311          char user[SMB_USERNAME_MAXLEN];
 275  312          DWORD enum_context;
 276  313          DWORD status;
 277  314  
 278  315          smb_ipc_get_user(user, SMB_USERNAME_MAXLEN);
 279  316  
 280  317          status = lsar_open(server, domain, user, &domain_handle);
 281  318          if (status != 0)
 282  319                  return (status);
 283  320  
 284  321          enum_context = 0;
 285  322  
 286  323          status = lsar_enum_trusted_domains_ex(&domain_handle, &enum_context,
 287  324              info);
 288  325          if (status == NT_STATUS_NO_MORE_ENTRIES) {
 289  326                  /*
 290  327                   * STATUS_NO_MORE_ENTRIES indicates that we
 291  328                   * have all of the available information.
 292  329                   */
 293  330                  status = NT_STATUS_SUCCESS;
 294  331          }
 295  332  
 296  333          (void) lsar_close(&domain_handle);
 297  334          return (status);
 298  335  }
 299  336  
 300  337  /*
 301  338   * Lookup well known accounts table
 302  339   *
 303  340   * Return status:
 304  341   *
 305  342   *   NT_STATUS_SUCCESS          Account is translated successfully
 306  343   *   NT_STATUS_NOT_FOUND        This is not a well known account
 307  344   *   NT_STATUS_NONE_MAPPED      Account is found but domains don't match
 308  345   *   NT_STATUS_NO_MEMORY        Memory shortage
 309  346   *   NT_STATUS_INTERNAL_ERROR   Internal error/unexpected failure
 310  347   */
 311  348  static uint32_t
 312  349  lsa_lookup_name_builtin(char *domain, char *name, smb_account_t *info)
 313  350  {
 314  351          smb_wka_t *wka;
 315  352          char *wkadom;
 316  353  
 317  354          bzero(info, sizeof (smb_account_t));
 318  355  
 319  356          if ((wka = smb_wka_lookup_name(name)) == NULL)
 320  357                  return (NT_STATUS_NOT_FOUND);
 321  358  
 322  359          if ((wkadom = smb_wka_get_domain(wka->wka_domidx)) == NULL)
 323  360                  return (NT_STATUS_INTERNAL_ERROR);
 324  361  
 325  362          if ((domain != NULL) && (smb_strcasecmp(domain, wkadom, 0) != 0))
 326  363                  return (NT_STATUS_NONE_MAPPED);
 327  364  
 328  365          info->a_name = strdup(name);
 329  366          info->a_sid = smb_sid_dup(wka->wka_binsid);
 330  367          info->a_domain = strdup(wkadom);
 331  368          info->a_domsid = smb_sid_split(wka->wka_binsid, &info->a_rid);
 332  369          info->a_type = wka->wka_type;
 333  370  
 334  371          if (!smb_account_validate(info)) {
 335  372                  smb_account_free(info);
 336  373                  return (NT_STATUS_NO_MEMORY);
 337  374          }
 338  375  
 339  376          return (NT_STATUS_SUCCESS);
 340  377  }
 341  378  
 342  379  /*
 343  380   * Lookup a domain account by its name.
 344  381   *
 345  382   * The information is returned in the user_info structure.
 346  383   * The caller is responsible for allocating and releasing
 347  384   * this structure.
 348  385   *
 349  386   * Returns NT status codes. (LSA-ized)
 350  387   */
 351  388  static uint32_t
 352  389  lsa_lookup_name_domain(char *account_name, smb_account_t *info)
 353  390  {
 354  391          mlsvc_handle_t domain_handle;
 355  392          smb_domainex_t dinfo;
 356  393          char user[SMB_USERNAME_MAXLEN];
 357  394          uint32_t status;
 358  395  
 359  396          smb_ipc_get_user(user, SMB_USERNAME_MAXLEN);
 360  397  
 361  398          if (!smb_domain_getinfo(&dinfo))
 362  399                  return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
 363  400  
 364  401          status = lsar_open(dinfo.d_dci.dc_name, dinfo.d_primary.di_nbname,
 365  402              user, &domain_handle);
 366  403          if (status != 0)
 367  404                  return (lsa_map_status(status));
 368  405  
 369  406          status = lsar_lookup_names(&domain_handle, account_name, info);
 370  407  
 371  408          (void) lsar_close(&domain_handle);
 372  409          return (status);
 373  410  }
 374  411  
 375  412  /*
 376  413   * lsa_lookup_privs
 377  414   *
 378  415   * Request the privileges associated with the specified account. In
 379  416   * order to get the privileges, we first have to lookup the name on
 380  417   * the specified domain controller and obtain the appropriate SID.
 381  418   * The SID can then be used to open the account and obtain the
 382  419   * account privileges. The results from both the name lookup and the
 383  420   * privileges are returned in the user_info structure. The caller is
 384  421   * responsible for allocating and releasing this structure.
 385  422   *
 386  423   * Returns NT status codes. (LSA-ized)
 387  424   */
 388  425  /*ARGSUSED*/
 389  426  DWORD
 390  427  lsa_lookup_privs(char *account_name, char *target_name, smb_account_t *ainfo)
 391  428  {
 392  429          mlsvc_handle_t domain_handle;
 393  430          smb_domainex_t dinfo;
 394  431          char user[SMB_USERNAME_MAXLEN];
 395  432          DWORD status;
 396  433  
 397  434          smb_ipc_get_user(user, SMB_USERNAME_MAXLEN);
 398  435  
 399  436          if (!smb_domain_getinfo(&dinfo))
 400  437                  return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
 401  438  
 402  439          status = lsar_open(dinfo.d_dci.dc_name, dinfo.d_primary.di_nbname,
 403  440              user, &domain_handle);
 404  441          if (status != 0)
 405  442                  return (lsa_map_status(status));
 406  443  
 407  444          status = lsa_list_accounts(&domain_handle);
 408  445          (void) lsar_close(&domain_handle);
 409  446          return (status);
 410  447  }
 411  448  
 412  449  /*
 413  450   * lsa_list_privs
 414  451   *
 415  452   * List the privileges supported by the specified server.
 416  453   * This function is only intended for diagnostics.
 417  454   *
 418  455   * Returns NT status codes. (LSA-ized)
 419  456   */
 420  457  DWORD
 421  458  lsa_list_privs(char *server, char *domain)
 422  459  {
 423  460          static char name[128];
 424  461          static struct ms_luid luid;
 425  462          mlsvc_handle_t domain_handle;
 426  463          char user[SMB_USERNAME_MAXLEN];
 427  464          DWORD status;
 428  465          int rc;
 429  466          int i;
 430  467  
 431  468          smb_ipc_get_user(user, SMB_USERNAME_MAXLEN);
 432  469  
 433  470          status = lsar_open(server, domain, user, &domain_handle);
 434  471          if (status != 0)
 435  472                  return (lsa_map_status(status));
 436  473  
 437  474          for (i = 0; i < 30; ++i) {
 438  475                  luid.low_part = i;
 439  476                  rc = lsar_lookup_priv_name(&domain_handle, &luid, name, 128);
 440  477                  if (rc != 0)
 441  478                          continue;
 442  479  
 443  480                  (void) lsar_lookup_priv_value(&domain_handle, name, &luid);
 444  481                  (void) lsar_lookup_priv_display_name(&domain_handle, name,
 445  482                      name, 128);
 446  483          }
 447  484  
 448  485          (void) lsar_close(&domain_handle);
 449  486          return (NT_STATUS_SUCCESS);
 450  487  }
 451  488  
 452  489  /*
 453  490   * lsa_list_accounts
 454  491   *
 455  492   * This function can be used to list the accounts in the specified
 456  493   * domain. For now the SIDs are just listed in the system log.
 457  494   *
 458  495   * Returns NT status
 459  496   */
 460  497  static DWORD
 461  498  lsa_list_accounts(mlsvc_handle_t *domain_handle)
 462  499  {
 463  500          mlsvc_handle_t account_handle;
 464  501          struct mslsa_EnumAccountBuf accounts;
 465  502          struct mslsa_sid *sid;
 466  503          smb_account_t ainfo;
 467  504          DWORD enum_context = 0;
 468  505          DWORD status;
 469  506          int i;
 470  507  
 471  508          bzero(&accounts, sizeof (struct mslsa_EnumAccountBuf));
 472  509  
 473  510          do {
 474  511                  status = lsar_enum_accounts(domain_handle, &enum_context,
 475  512                      &accounts);
 476  513                  if (status != 0)
 477  514                          return (status);
 478  515  
 479  516                  for (i = 0; i < accounts.entries_read; ++i) {
 480  517                          sid = accounts.info[i].sid;
 481  518  
 482  519                          if (lsar_open_account(domain_handle, sid,
 483  520                              &account_handle) == 0) {
 484  521                                  (void) lsar_enum_privs_account(&account_handle,
 485  522                                      &ainfo);
 486  523                                  (void) lsar_close(&account_handle);
 487  524                          }
 488  525  
 489  526                          free(accounts.info[i].sid);
 490  527                  }
 491  528  
 492  529                  if (accounts.info)
 493  530                          free(accounts.info);
 494  531          } while (status == 0 && accounts.entries_read != 0);
 495  532  
 496  533          return (0);
 497  534  }
 498  535  
 499  536  /*
 500  537   * Lookup well known accounts table for the given SID
 501  538   *
 502  539   * Return status:
 503  540   *
 504  541   *   NT_STATUS_SUCCESS          Account is translated successfully
 505  542   *   NT_STATUS_NOT_FOUND        This is not a well known account
 506  543   *   NT_STATUS_NO_MEMORY        Memory shortage
 507  544   *   NT_STATUS_INTERNAL_ERROR   Internal error/unexpected failure
 508  545   */
 509  546  static uint32_t
 510  547  lsa_lookup_sid_builtin(smb_sid_t *sid, smb_account_t *ainfo)
 511  548  {
 512  549          smb_wka_t *wka;
 513  550          char *wkadom;
 514  551  
 515  552          bzero(ainfo, sizeof (smb_account_t));
 516  553  
 517  554          if ((wka = smb_wka_lookup_sid(sid)) == NULL)
 518  555                  return (NT_STATUS_NOT_FOUND);
 519  556  
 520  557          if ((wkadom = smb_wka_get_domain(wka->wka_domidx)) == NULL)
 521  558                  return (NT_STATUS_INTERNAL_ERROR);
 522  559  
 523  560          ainfo->a_name = strdup(wka->wka_name);
 524  561          ainfo->a_sid = smb_sid_dup(wka->wka_binsid);
 525  562          ainfo->a_domain = strdup(wkadom);
 526  563          ainfo->a_domsid = smb_sid_split(ainfo->a_sid, &ainfo->a_rid);
 527  564          ainfo->a_type = wka->wka_type;
 528  565  
 529  566          if (!smb_account_validate(ainfo)) {
 530  567                  smb_account_free(ainfo);
 531  568                  return (NT_STATUS_NO_MEMORY);
 532  569          }
 533  570  
 534  571          return (NT_STATUS_SUCCESS);
 535  572  }
 536  573  
 537  574  /*
 538  575   * Lookup a domain account by its SID.
 539  576   *
 540  577   * The information is returned in the user_info structure.
 541  578   * The caller is responsible for allocating and releasing
 542  579   * this structure.
 543  580   *
 544  581   * Returns NT status codes. (LSA-ized)
 545  582   */
 546  583  static uint32_t
 547  584  lsa_lookup_sid_domain(smb_sid_t *sid, smb_account_t *ainfo)
 548  585  {
 549  586          mlsvc_handle_t domain_handle;
 550  587          smb_domainex_t dinfo;
 551  588          char user[SMB_USERNAME_MAXLEN];
 552  589          uint32_t status;
 553  590  
 554  591          smb_ipc_get_user(user, SMB_USERNAME_MAXLEN);
 555  592  
 556  593          if (!smb_domain_getinfo(&dinfo))
 557  594                  return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
 558  595  
 559  596          status = lsar_open(dinfo.d_dci.dc_name, dinfo.d_primary.di_nbname,
 560  597              user, &domain_handle);
 561  598          if (status != 0)
 562  599                  return (lsa_map_status(status));
 563  600  
 564  601          status = lsar_lookup_sids(&domain_handle, sid, ainfo);
 565  602  
 566  603          (void) lsar_close(&domain_handle);
 567  604          return (status);
 568  605  }
 569  606  
 570  607  /*
 571  608   * Most functions that call the local security authority expect
 572  609   * only a limited set of status returns.  This function maps the
 573  610   * status we get from talking to our domain controller into one
 574  611   * that LSA functions can return.  Most common errors become:
 575  612   * NT_STATUS_CANT_ACCESS_DOMAIN_INFO (when no DC etc.)
 576  613   */
 577  614  static uint32_t
 578  615  lsa_map_status(uint32_t status)
 579  616  {
 580  617          switch (status) {
 581  618          case NT_STATUS_SUCCESS:
 582  619                  break;
 583  620          case NT_STATUS_INVALID_PARAMETER:       /* rpc bind */
 584  621                  break;
 585  622          case NT_STATUS_NO_MEMORY:
 586  623                  break;
 587  624          case NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND:
 588  625          case NT_STATUS_BAD_NETWORK_PATH:        /* get server addr */
 589  626          case NT_STATUS_NETWORK_ACCESS_DENIED:   /* authentication */
 590  627          case NT_STATUS_BAD_NETWORK_NAME:        /* tree connect */
 591  628          case NT_STATUS_ACCESS_DENIED:           /* open pipe */
 592  629                  status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
 593  630                  break;
 594  631          default:
 595  632                  status = NT_STATUS_UNSUCCESSFUL;
 596  633                  break;
 597  634          }
 598  635          return (status);
 599  636  }
  
    | 
      ↓ open down ↓ | 
    463 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX