root/source4/rpc_server/lsa/dcesrv_lsa.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. dcesrv_lsa_Close
  2. dcesrv_lsa_Delete
  3. dcesrv_lsa_DeleteObject
  4. dcesrv_lsa_EnumPrivs
  5. dcesrv_lsa_QuerySecurity
  6. dcesrv_lsa_SetSecObj
  7. dcesrv_lsa_ChangePassword
  8. dcesrv_dssetup_DsRoleGetPrimaryDomainInformation
  9. dcesrv_lsa_info_AccountDomain
  10. dcesrv_lsa_info_DNS
  11. dcesrv_lsa_QueryInfoPolicy2
  12. dcesrv_lsa_QueryInfoPolicy
  13. dcesrv_lsa_SetInfoPolicy
  14. dcesrv_lsa_ClearAuditLog
  15. dcesrv_lsa_CreateAccount
  16. dcesrv_lsa_EnumAccounts
  17. dcesrv_lsa_CreateTrustedDomain_base
  18. dcesrv_lsa_CreateTrustedDomainEx2
  19. dcesrv_lsa_CreateTrustedDomainEx
  20. dcesrv_lsa_CreateTrustedDomain
  21. dcesrv_lsa_OpenTrustedDomain
  22. dcesrv_lsa_OpenTrustedDomainByName
  23. dcesrv_lsa_SetTrustedDomainInfo
  24. dcesrv_lsa_SetInformationTrustedDomain
  25. dcesrv_lsa_DeleteTrustedDomain
  26. fill_trust_domain_ex
  27. dcesrv_lsa_QueryTrustedDomainInfo
  28. dcesrv_lsa_QueryTrustedDomainInfoBySid
  29. dcesrv_lsa_SetTrustedDomainInfoByName
  30. dcesrv_lsa_QueryTrustedDomainInfoByName
  31. dcesrv_lsa_CloseTrustedDomainEx
  32. compare_DomainInfo
  33. dcesrv_lsa_EnumTrustDom
  34. compare_TrustDomainInfoInfoEx
  35. dcesrv_lsa_EnumTrustedDomainsEx
  36. dcesrv_lsa_OpenAccount
  37. dcesrv_lsa_EnumPrivsAccount
  38. dcesrv_lsa_EnumAccountRights
  39. dcesrv_lsa_AddRemoveAccountRights
  40. dcesrv_lsa_AddPrivilegesToAccount
  41. dcesrv_lsa_RemovePrivilegesFromAccount
  42. dcesrv_lsa_GetQuotasForAccount
  43. dcesrv_lsa_SetQuotasForAccount
  44. dcesrv_lsa_GetSystemAccessAccount
  45. dcesrv_lsa_SetSystemAccessAccount
  46. dcesrv_lsa_CreateSecret
  47. dcesrv_lsa_OpenSecret
  48. dcesrv_lsa_SetSecret
  49. dcesrv_lsa_QuerySecret
  50. dcesrv_lsa_LookupPrivValue
  51. dcesrv_lsa_LookupPrivName
  52. dcesrv_lsa_LookupPrivDisplayName
  53. dcesrv_lsa_EnumAccountsWithUserRight
  54. dcesrv_lsa_AddAccountRights
  55. dcesrv_lsa_RemoveAccountRights
  56. dcesrv_lsa_StorePrivateData
  57. dcesrv_lsa_RetrievePrivateData
  58. dcesrv_lsa_GetUserName
  59. dcesrv_lsa_SetInfoPolicy2
  60. dcesrv_lsa_QueryDomainInformationPolicy
  61. dcesrv_lsa_SetDomainInformationPolicy
  62. dcesrv_lsa_TestCall
  63. dcesrv_lsa_CREDRWRITE
  64. dcesrv_lsa_CREDRREAD
  65. dcesrv_lsa_CREDRENUMERATE
  66. dcesrv_lsa_CREDRWRITEDOMAINCREDENTIALS
  67. dcesrv_lsa_CREDRREADDOMAINCREDENTIALS
  68. dcesrv_lsa_CREDRDELETE
  69. dcesrv_lsa_CREDRGETTARGETINFO
  70. dcesrv_lsa_CREDRPROFILELOADED
  71. dcesrv_lsa_CREDRGETSESSIONTYPES
  72. dcesrv_lsa_LSARREGISTERAUDITEVENT
  73. dcesrv_lsa_LSARGENAUDITEVENT
  74. dcesrv_lsa_LSARUNREGISTERAUDITEVENT
  75. dcesrv_lsa_lsaRQueryForestTrustInformation
  76. dcesrv_lsa_LSARSETFORESTTRUSTINFORMATION
  77. dcesrv_lsa_CREDRRENAME
  78. dcesrv_lsa_LSAROPENPOLICYSCE
  79. dcesrv_lsa_LSARADTREGISTERSECURITYEVENTSOURCE
  80. dcesrv_lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
  81. dcesrv_lsa_LSARADTREPORTSECURITYEVENT
  82. dcesrv_dssetup_DsRoleDnsNameToFlatName
  83. dcesrv_dssetup_DsRoleDcAsDc
  84. dcesrv_dssetup_DsRoleDcAsReplica
  85. dcesrv_dssetup_DsRoleDemoteDc
  86. dcesrv_dssetup_DsRoleGetDcOperationProgress
  87. dcesrv_dssetup_DsRoleGetDcOperationResults
  88. dcesrv_dssetup_DsRoleCancel
  89. dcesrv_dssetup_DsRoleServerSaveStateForUpgrade
  90. dcesrv_dssetup_DsRoleUpgradeDownlevelServer
  91. dcesrv_dssetup_DsRoleAbortDownlevelServerUpgrade
  92. dcerpc_server_lsa_init

   1 /* need access mask/acl implementation */
   2 
   3 /* 
   4    Unix SMB/CIFS implementation.
   5 
   6    endpoint server for the lsarpc pipe
   7 
   8    Copyright (C) Andrew Tridgell 2004
   9    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2008
  10    
  11    This program is free software; you can redistribute it and/or modify
  12    it under the terms of the GNU General Public License as published by
  13    the Free Software Foundation; either version 3 of the License, or
  14    (at your option) any later version.
  15    
  16    This program is distributed in the hope that it will be useful,
  17    but WITHOUT ANY WARRANTY; without even the implied warranty of
  18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19    GNU General Public License for more details.
  20    
  21    You should have received a copy of the GNU General Public License
  22    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  23 */
  24 
  25 #include "rpc_server/lsa/lsa.h"
  26 #include "../lib/util/util_ldb.h"
  27 #include "libcli/ldap/ldap_ndr.h"
  28 #include "system/kerberos.h"
  29 #include "auth/kerberos/kerberos.h"
  30 #include "librpc/gen_ndr/ndr_drsblobs.h"
  31 #include "librpc/gen_ndr/ndr_lsa.h"
  32 #include "../lib/crypto/crypto.h"
  33 
  34 /*
  35   this type allows us to distinguish handle types
  36 */
  37 
  38 /*
  39   state associated with a lsa_OpenAccount() operation
  40 */
  41 struct lsa_account_state {
  42         struct lsa_policy_state *policy;
  43         uint32_t access_mask;
  44         struct dom_sid *account_sid;
  45 };
  46 
  47 
  48 /*
  49   state associated with a lsa_OpenSecret() operation
  50 */
  51 struct lsa_secret_state {
  52         struct lsa_policy_state *policy;
  53         uint32_t access_mask;
  54         struct ldb_dn *secret_dn;
  55         struct ldb_context *sam_ldb;
  56         bool global;
  57 };
  58 
  59 /*
  60   state associated with a lsa_OpenTrustedDomain() operation
  61 */
  62 struct lsa_trusted_domain_state {
  63         struct lsa_policy_state *policy;
  64         uint32_t access_mask;
  65         struct ldb_dn *trusted_domain_dn;
  66         struct ldb_dn *trusted_domain_user_dn;
  67 };
  68 
  69 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call, 
  70                                       TALLOC_CTX *mem_ctx,
  71                                       struct lsa_EnumAccountRights *r);
  72 
  73 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call, 
  74                                            TALLOC_CTX *mem_ctx,
  75                                            struct lsa_policy_state *state,
  76                                            int ldb_flag,
  77                                            struct dom_sid *sid,
  78                                            const struct lsa_RightSet *rights);
  79 
  80 /* 
  81   lsa_Close 
  82 */
  83 static NTSTATUS dcesrv_lsa_Close(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
  84                           struct lsa_Close *r)
  85 {
  86         struct dcesrv_handle *h;
  87 
  88         *r->out.handle = *r->in.handle;
  89 
  90         DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
  91 
  92         talloc_free(h);
  93 
  94         ZERO_STRUCTP(r->out.handle);
  95 
  96         return NT_STATUS_OK;
  97 }
  98 
  99 
 100 /* 
 101   lsa_Delete 
 102 */
 103 static NTSTATUS dcesrv_lsa_Delete(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 104                            struct lsa_Delete *r)
 105 {
 106         return NT_STATUS_NOT_SUPPORTED;
 107 }
 108 
 109 
 110 /* 
 111   lsa_DeleteObject
 112 */
 113 static NTSTATUS dcesrv_lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 114                        struct lsa_DeleteObject *r)
 115 {
 116         struct dcesrv_handle *h;
 117         int ret;
 118 
 119         DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
 120 
 121         if (h->wire_handle.handle_type == LSA_HANDLE_SECRET) {
 122                 struct lsa_secret_state *secret_state = h->data;
 123 
 124                 /* Ensure user is permitted to delete this... */
 125                 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
 126                 {
 127                 case SECURITY_SYSTEM:
 128                 case SECURITY_ADMINISTRATOR:
 129                         break;
 130                 default:
 131                         /* Users and annonymous are not allowed delete things */
 132                         return NT_STATUS_ACCESS_DENIED;
 133                 }
 134 
 135                 ret = ldb_delete(secret_state->sam_ldb, 
 136                                  secret_state->secret_dn);
 137                 talloc_free(h);
 138                 if (ret != 0) {
 139                         return NT_STATUS_INVALID_HANDLE;
 140                 }
 141 
 142                 ZERO_STRUCTP(r->out.handle);
 143 
 144                 return NT_STATUS_OK;
 145         } else if (h->wire_handle.handle_type == LSA_HANDLE_TRUSTED_DOMAIN) {
 146                 struct lsa_trusted_domain_state *trusted_domain_state = 
 147                         talloc_get_type(h->data, struct lsa_trusted_domain_state);
 148                 ret = ldb_transaction_start(trusted_domain_state->policy->sam_ldb);
 149                 if (ret != 0) {
 150                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
 151                 }
 152 
 153                 ret = ldb_delete(trusted_domain_state->policy->sam_ldb, 
 154                                  trusted_domain_state->trusted_domain_dn);
 155                 if (ret != 0) {
 156                         ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
 157                         return NT_STATUS_INVALID_HANDLE;
 158                 }
 159 
 160                 if (trusted_domain_state->trusted_domain_user_dn) {
 161                         ret = ldb_delete(trusted_domain_state->policy->sam_ldb, 
 162                                          trusted_domain_state->trusted_domain_user_dn);
 163                         if (ret != 0) {
 164                                 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
 165                                 return NT_STATUS_INVALID_HANDLE;
 166                         }
 167                 }
 168 
 169                 ret = ldb_transaction_commit(trusted_domain_state->policy->sam_ldb);
 170                 if (ret != 0) {
 171                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
 172                 }
 173                 talloc_free(h);
 174                 ZERO_STRUCTP(r->out.handle);
 175 
 176                 return NT_STATUS_OK;
 177         } else if (h->wire_handle.handle_type == LSA_HANDLE_ACCOUNT) {
 178                 struct lsa_RightSet *rights;
 179                 struct lsa_account_state *astate;
 180                 struct lsa_EnumAccountRights r2;
 181                 NTSTATUS status;
 182 
 183                 rights = talloc(mem_ctx, struct lsa_RightSet);
 184 
 185                 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
 186                 
 187                 astate = h->data;
 188 
 189                 r2.in.handle = &astate->policy->handle->wire_handle;
 190                 r2.in.sid = astate->account_sid;
 191                 r2.out.rights = rights;
 192 
 193                 /* dcesrv_lsa_EnumAccountRights takes a LSA_HANDLE_POLICY,
 194                    but we have a LSA_HANDLE_ACCOUNT here, so this call
 195                    will always fail */
 196                 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
 197                 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
 198                         return NT_STATUS_OK;
 199                 }
 200 
 201                 if (!NT_STATUS_IS_OK(status)) {
 202                         return status;
 203                 }
 204 
 205                 status = dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy, 
 206                                                     LDB_FLAG_MOD_DELETE, astate->account_sid,
 207                                                     r2.out.rights);
 208                 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
 209                         return NT_STATUS_OK;
 210                 }
 211 
 212                 if (!NT_STATUS_IS_OK(status)) {
 213                         return status;
 214                 }
 215 
 216                 ZERO_STRUCTP(r->out.handle);
 217         } 
 218         
 219         return NT_STATUS_INVALID_HANDLE;
 220 }
 221 
 222 
 223 /* 
 224   lsa_EnumPrivs 
 225 */
 226 static NTSTATUS dcesrv_lsa_EnumPrivs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 227                               struct lsa_EnumPrivs *r)
 228 {
 229         struct dcesrv_handle *h;
 230         struct lsa_policy_state *state;
 231         int i;
 232         const char *privname;
 233 
 234         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
 235 
 236         state = h->data;
 237 
 238         i = *r->in.resume_handle;
 239         if (i == 0) i = 1;
 240 
 241         while ((privname = sec_privilege_name(i)) &&
 242                r->out.privs->count < r->in.max_count) {
 243                 struct lsa_PrivEntry *e;
 244 
 245                 r->out.privs->privs = talloc_realloc(r->out.privs,
 246                                                        r->out.privs->privs, 
 247                                                        struct lsa_PrivEntry, 
 248                                                        r->out.privs->count+1);
 249                 if (r->out.privs->privs == NULL) {
 250                         return NT_STATUS_NO_MEMORY;
 251                 }
 252                 e = &r->out.privs->privs[r->out.privs->count];
 253                 e->luid.low = i;
 254                 e->luid.high = 0;
 255                 e->name.string = privname;
 256                 r->out.privs->count++;
 257                 i++;
 258         }
 259 
 260         *r->out.resume_handle = i;
 261 
 262         return NT_STATUS_OK;
 263 }
 264 
 265 
 266 /* 
 267   lsa_QuerySecObj 
 268 */
 269 static NTSTATUS dcesrv_lsa_QuerySecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 270                                   struct lsa_QuerySecurity *r)
 271 {
 272         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
 273 }
 274 
 275 
 276 /* 
 277   lsa_SetSecObj 
 278 */
 279 static NTSTATUS dcesrv_lsa_SetSecObj(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 280                               struct lsa_SetSecObj *r)
 281 {
 282         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
 283 }
 284 
 285 
 286 /* 
 287   lsa_ChangePassword 
 288 */
 289 static NTSTATUS dcesrv_lsa_ChangePassword(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 290                                    struct lsa_ChangePassword *r)
 291 {
 292         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
 293 }
 294 
 295 /* 
 296   dssetup_DsRoleGetPrimaryDomainInformation 
 297 
 298   This is not an LSA call, but is the only call left on the DSSETUP
 299   pipe (after the pipe was truncated), and needs lsa_get_policy_state
 300 */
 301 static WERROR dcesrv_dssetup_DsRoleGetPrimaryDomainInformation(struct dcesrv_call_state *dce_call, 
     /* [<][>][^][v][top][bottom][index][help] */
 302                                                  TALLOC_CTX *mem_ctx,
 303                                                  struct dssetup_DsRoleGetPrimaryDomainInformation *r)
 304 {
 305         union dssetup_DsRoleInfo *info;
 306 
 307         info = talloc(mem_ctx, union dssetup_DsRoleInfo);
 308         W_ERROR_HAVE_NO_MEMORY(info);
 309 
 310         switch (r->in.level) {
 311         case DS_ROLE_BASIC_INFORMATION:
 312         {
 313                 enum dssetup_DsRole role = DS_ROLE_STANDALONE_SERVER;
 314                 uint32_t flags = 0;
 315                 const char *domain = NULL;
 316                 const char *dns_domain = NULL;
 317                 const char *forest = NULL;
 318                 struct GUID domain_guid;
 319                 struct lsa_policy_state *state;
 320 
 321                 NTSTATUS status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx, &state);
 322                 if (!NT_STATUS_IS_OK(status)) {
 323                         return ntstatus_to_werror(status);
 324                 }
 325 
 326                 ZERO_STRUCT(domain_guid);
 327 
 328                 switch (lp_server_role(dce_call->conn->dce_ctx->lp_ctx)) {
 329                 case ROLE_STANDALONE:
 330                         role            = DS_ROLE_STANDALONE_SERVER;
 331                         break;
 332                 case ROLE_DOMAIN_MEMBER:
 333                         role            = DS_ROLE_MEMBER_SERVER;
 334                         break;
 335                 case ROLE_DOMAIN_CONTROLLER:
 336                         if (samdb_is_pdc(state->sam_ldb)) {
 337                                 role    = DS_ROLE_PRIMARY_DC;
 338                         } else {
 339                                 role    = DS_ROLE_BACKUP_DC;
 340                         }
 341                         break;
 342                 }
 343 
 344                 switch (lp_server_role(dce_call->conn->dce_ctx->lp_ctx)) {
 345                 case ROLE_STANDALONE:
 346                         domain          = talloc_strdup(mem_ctx, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx));
 347                         W_ERROR_HAVE_NO_MEMORY(domain);
 348                         break;
 349                 case ROLE_DOMAIN_MEMBER:
 350                         domain          = talloc_strdup(mem_ctx, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx));
 351                         W_ERROR_HAVE_NO_MEMORY(domain);
 352                         /* TODO: what is with dns_domain and forest and guid? */
 353                         break;
 354                 case ROLE_DOMAIN_CONTROLLER:
 355                         flags           = DS_ROLE_PRIMARY_DS_RUNNING;
 356 
 357                         if (state->mixed_domain == 1) {
 358                                 flags   |= DS_ROLE_PRIMARY_DS_MIXED_MODE;
 359                         }
 360                         
 361                         domain          = state->domain_name;
 362                         dns_domain      = state->domain_dns;
 363                         forest          = state->forest_dns;
 364 
 365                         domain_guid     = state->domain_guid;
 366                         flags   |= DS_ROLE_PRIMARY_DOMAIN_GUID_PRESENT;
 367                         break;
 368                 }
 369 
 370                 info->basic.role        = role; 
 371                 info->basic.flags       = flags;
 372                 info->basic.domain      = domain;
 373                 info->basic.dns_domain  = dns_domain;
 374                 info->basic.forest      = forest;
 375                 info->basic.domain_guid = domain_guid;
 376 
 377                 r->out.info = info;
 378                 return WERR_OK;
 379         }
 380         case DS_ROLE_UPGRADE_STATUS:
 381         {
 382                 info->upgrade.upgrading     = DS_ROLE_NOT_UPGRADING;
 383                 info->upgrade.previous_role = DS_ROLE_PREVIOUS_UNKNOWN;
 384 
 385                 r->out.info = info;
 386                 return WERR_OK;
 387         }
 388         case DS_ROLE_OP_STATUS:
 389         {
 390                 info->opstatus.status = DS_ROLE_OP_IDLE;
 391 
 392                 r->out.info = info;
 393                 return WERR_OK;
 394         }
 395         default:
 396                 return WERR_INVALID_PARAM;
 397         }
 398 
 399         return WERR_INVALID_PARAM;
 400 }
 401 
 402 /*
 403   fill in the AccountDomain info
 404 */
 405 static NTSTATUS dcesrv_lsa_info_AccountDomain(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 406                                        struct lsa_DomainInfo *info)
 407 {
 408         info->name.string = state->domain_name;
 409         info->sid         = state->domain_sid;
 410 
 411         return NT_STATUS_OK;
 412 }
 413 
 414 /*
 415   fill in the DNS domain info
 416 */
 417 static NTSTATUS dcesrv_lsa_info_DNS(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 418                              struct lsa_DnsDomainInfo *info)
 419 {
 420         info->name.string = state->domain_name;
 421         info->sid         = state->domain_sid;
 422         info->dns_domain.string = state->domain_dns;
 423         info->dns_forest.string = state->forest_dns;
 424         info->domain_guid       = state->domain_guid;
 425 
 426         return NT_STATUS_OK;
 427 }
 428 
 429 /* 
 430   lsa_QueryInfoPolicy2
 431 */
 432 static NTSTATUS dcesrv_lsa_QueryInfoPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 433                                      struct lsa_QueryInfoPolicy2 *r)
 434 {
 435         struct lsa_policy_state *state;
 436         struct dcesrv_handle *h;
 437         union lsa_PolicyInformation *info;
 438 
 439         *r->out.info = NULL;
 440 
 441         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
 442 
 443         state = h->data;
 444 
 445         info = talloc_zero(mem_ctx, union lsa_PolicyInformation);
 446         if (!info) {
 447                 return NT_STATUS_NO_MEMORY;
 448         }
 449         *r->out.info = info;
 450 
 451         switch (r->in.level) {
 452         case LSA_POLICY_INFO_AUDIT_LOG:
 453                 /* we don't need to fill in any of this */
 454                 ZERO_STRUCT(info->audit_log);
 455                 return NT_STATUS_OK;
 456         case LSA_POLICY_INFO_AUDIT_EVENTS:
 457                 /* we don't need to fill in any of this */
 458                 ZERO_STRUCT(info->audit_events);
 459                 return NT_STATUS_OK;
 460         case LSA_POLICY_INFO_PD:
 461                 /* we don't need to fill in any of this */
 462                 ZERO_STRUCT(info->pd);
 463                 return NT_STATUS_OK;
 464 
 465         case LSA_POLICY_INFO_DOMAIN:
 466                 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->domain);
 467         case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
 468                 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->account_domain);
 469         case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
 470                 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->l_account_domain);
 471 
 472 
 473         case LSA_POLICY_INFO_ROLE:
 474                 info->role.role = LSA_ROLE_PRIMARY;
 475                 return NT_STATUS_OK;
 476 
 477         case LSA_POLICY_INFO_DNS:
 478         case LSA_POLICY_INFO_DNS_INT:
 479                 return dcesrv_lsa_info_DNS(state, mem_ctx, &info->dns);
 480 
 481         case LSA_POLICY_INFO_REPLICA:
 482                 ZERO_STRUCT(info->replica);
 483                 return NT_STATUS_OK;
 484 
 485         case LSA_POLICY_INFO_QUOTA:
 486                 ZERO_STRUCT(info->quota);
 487                 return NT_STATUS_OK;
 488 
 489         case LSA_POLICY_INFO_MOD:
 490         case LSA_POLICY_INFO_AUDIT_FULL_SET:
 491         case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
 492                 /* windows gives INVALID_PARAMETER */
 493                 *r->out.info = NULL;
 494                 return NT_STATUS_INVALID_PARAMETER;
 495         }
 496 
 497         *r->out.info = NULL;
 498         return NT_STATUS_INVALID_INFO_CLASS;
 499 }
 500 
 501 /* 
 502   lsa_QueryInfoPolicy 
 503 */
 504 static NTSTATUS dcesrv_lsa_QueryInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 505                                     struct lsa_QueryInfoPolicy *r)
 506 {
 507         struct lsa_QueryInfoPolicy2 r2;
 508         NTSTATUS status;
 509 
 510         ZERO_STRUCT(r2);
 511 
 512         r2.in.handle = r->in.handle;
 513         r2.in.level = r->in.level;
 514         r2.out.info = r->out.info;
 515         
 516         status = dcesrv_lsa_QueryInfoPolicy2(dce_call, mem_ctx, &r2);
 517 
 518         return status;
 519 }
 520 
 521 /* 
 522   lsa_SetInfoPolicy 
 523 */
 524 static NTSTATUS dcesrv_lsa_SetInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 525                                   struct lsa_SetInfoPolicy *r)
 526 {
 527         /* need to support this */
 528         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
 529 }
 530 
 531 
 532 /* 
 533   lsa_ClearAuditLog 
 534 */
 535 static NTSTATUS dcesrv_lsa_ClearAuditLog(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 536                                   struct lsa_ClearAuditLog *r)
 537 {
 538         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
 539 }
 540 
 541 
 542 /* 
 543   lsa_CreateAccount 
 544 
 545   This call does not seem to have any long-term effects, hence no database operations
 546 
 547   we need to talk to the MS product group to find out what this account database means!
 548 
 549   answer is that the lsa database is totally separate from the SAM and
 550   ldap databases. We are going to need a separate ldb to store these
 551   accounts. The SIDs on this account bear no relation to the SIDs in
 552   AD
 553 */
 554 static NTSTATUS dcesrv_lsa_CreateAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 555                                   struct lsa_CreateAccount *r)
 556 {
 557         struct lsa_account_state *astate;
 558 
 559         struct lsa_policy_state *state;
 560         struct dcesrv_handle *h, *ah;
 561 
 562         ZERO_STRUCTP(r->out.acct_handle);
 563 
 564         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
 565 
 566         state = h->data;
 567 
 568         astate = talloc(dce_call->conn, struct lsa_account_state);
 569         if (astate == NULL) {
 570                 return NT_STATUS_NO_MEMORY;
 571         }
 572 
 573         astate->account_sid = dom_sid_dup(astate, r->in.sid);
 574         if (astate->account_sid == NULL) {
 575                 talloc_free(astate);
 576                 return NT_STATUS_NO_MEMORY;
 577         }
 578         
 579         astate->policy = talloc_reference(astate, state);
 580         astate->access_mask = r->in.access_mask;
 581 
 582         ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
 583         if (!ah) {
 584                 talloc_free(astate);
 585                 return NT_STATUS_NO_MEMORY;
 586         }
 587 
 588         ah->data = talloc_steal(ah, astate);
 589 
 590         *r->out.acct_handle = ah->wire_handle;
 591 
 592         return NT_STATUS_OK;
 593 }
 594 
 595 
 596 /* 
 597   lsa_EnumAccounts 
 598 */
 599 static NTSTATUS dcesrv_lsa_EnumAccounts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 600                                  struct lsa_EnumAccounts *r)
 601 {
 602         struct dcesrv_handle *h;
 603         struct lsa_policy_state *state;
 604         int ret, i;
 605         struct ldb_message **res;
 606         const char * const attrs[] = { "objectSid", NULL};
 607         uint32_t count;
 608 
 609         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
 610 
 611         state = h->data;
 612 
 613         /* NOTE: This call must only return accounts that have at least
 614            one privilege set 
 615         */
 616         ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs, 
 617                            "(&(objectSid=*)(privilege=*))");
 618         if (ret < 0) {
 619                 return NT_STATUS_NO_SUCH_USER;
 620         }
 621 
 622         if (*r->in.resume_handle >= ret) {
 623                 return NT_STATUS_NO_MORE_ENTRIES;
 624         }
 625 
 626         count = ret - *r->in.resume_handle;
 627         if (count > r->in.num_entries) {
 628                 count = r->in.num_entries;
 629         }
 630 
 631         if (count == 0) {
 632                 return NT_STATUS_NO_MORE_ENTRIES;
 633         }
 634 
 635         r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, count);
 636         if (r->out.sids->sids == NULL) {
 637                 return NT_STATUS_NO_MEMORY;
 638         }
 639 
 640         for (i=0;i<count;i++) {
 641                 r->out.sids->sids[i].sid = 
 642                         samdb_result_dom_sid(r->out.sids->sids, 
 643                                              res[i + *r->in.resume_handle],
 644                                              "objectSid");
 645                 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
 646         }
 647 
 648         r->out.sids->num_sids = count;
 649         *r->out.resume_handle = count + *r->in.resume_handle;
 650 
 651         return NT_STATUS_OK;
 652         
 653 }
 654 
 655 
 656 /*
 657   lsa_CreateTrustedDomainEx2
 658 */
 659 static NTSTATUS dcesrv_lsa_CreateTrustedDomain_base(struct dcesrv_call_state *dce_call,
     /* [<][>][^][v][top][bottom][index][help] */
 660                                                     TALLOC_CTX *mem_ctx,
 661                                                     struct lsa_CreateTrustedDomainEx2 *r,
 662                                                     int op)
 663 {
 664         struct dcesrv_handle *policy_handle;
 665         struct lsa_policy_state *policy_state;
 666         struct lsa_trusted_domain_state *trusted_domain_state;
 667         struct dcesrv_handle *handle;
 668         struct ldb_message **msgs, *msg, *msg_user;
 669         const char *attrs[] = {
 670                 NULL
 671         };
 672         const char *netbios_name;
 673         const char *dns_name;
 674         const char *name;
 675         DATA_BLOB session_key = data_blob(NULL, 0);
 676         DATA_BLOB trustAuthIncoming, trustAuthOutgoing, auth_blob;
 677         struct trustDomainPasswords auth_struct;
 678         int ret;
 679         NTSTATUS nt_status;
 680         enum ndr_err_code ndr_err;
 681         
 682         DCESRV_PULL_HANDLE(policy_handle, r->in.policy_handle, LSA_HANDLE_POLICY);
 683         ZERO_STRUCTP(r->out.trustdom_handle);
 684         
 685         policy_state = policy_handle->data;
 686 
 687         nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
 688         if (!NT_STATUS_IS_OK(nt_status)) {
 689                 return nt_status;
 690         }
 691 
 692         netbios_name = r->in.info->netbios_name.string;
 693         if (!netbios_name) {
 694                 return NT_STATUS_INVALID_PARAMETER;
 695         }
 696         
 697         dns_name = r->in.info->domain_name.string;
 698         
 699         trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
 700         if (!trusted_domain_state) {
 701                 return NT_STATUS_NO_MEMORY;
 702         }
 703         trusted_domain_state->policy = policy_state;
 704 
 705         if (strcasecmp(netbios_name, "BUILTIN") == 0
 706             || (dns_name && strcasecmp(dns_name, "BUILTIN") == 0) 
 707             || (dom_sid_in_domain(policy_state->builtin_sid, r->in.info->sid))) {
 708                 return NT_STATUS_INVALID_PARAMETER;;
 709         }
 710 
 711         if (strcasecmp(netbios_name, policy_state->domain_name) == 0
 712             || strcasecmp(netbios_name, policy_state->domain_dns) == 0
 713             || (dns_name && strcasecmp(dns_name, policy_state->domain_dns) == 0) 
 714             || (dns_name && strcasecmp(dns_name, policy_state->domain_name) == 0)
 715             || (dom_sid_equal(policy_state->domain_sid, r->in.info->sid))) {
 716                 return NT_STATUS_CURRENT_DOMAIN_NOT_ALLOWED;
 717         }
 718 
 719         /* While this is a REF pointer, some of the functions that wrap this don't provide this */
 720         if (op == NDR_LSA_CREATETRUSTEDDOMAIN) {
 721                 /* No secrets are created at this time, for this function */
 722                 auth_struct.outgoing.count = 0;
 723                 auth_struct.incoming.count = 0;
 724         } else {
 725                 auth_blob = data_blob_const(r->in.auth_info->auth_blob.data, r->in.auth_info->auth_blob.size);
 726                 arcfour_crypt_blob(auth_blob.data, auth_blob.length, &session_key);
 727                 ndr_err = ndr_pull_struct_blob(&auth_blob, mem_ctx, 
 728                                                lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx),
 729                                                &auth_struct,
 730                                                (ndr_pull_flags_fn_t)ndr_pull_trustDomainPasswords);
 731                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
 732                         return NT_STATUS_INVALID_PARAMETER;
 733                 }                               
 734 
 735                 if (op == NDR_LSA_CREATETRUSTEDDOMAINEX) {
 736                         if (auth_struct.incoming.count > 1) {
 737                                 return NT_STATUS_INVALID_PARAMETER;
 738                         }
 739                 }
 740         }
 741 
 742         if (auth_struct.incoming.count) {
 743                 int i;
 744                 struct trustAuthInOutBlob incoming;
 745                 
 746                 incoming.count = auth_struct.incoming.count;
 747                 incoming.current = talloc(mem_ctx, struct AuthenticationInformationArray);
 748                 if (!incoming.current) {
 749                         return NT_STATUS_NO_MEMORY;
 750                 }
 751                 
 752                 incoming.current->array = *auth_struct.incoming.current;
 753                 if (!incoming.current->array) {
 754                         return NT_STATUS_NO_MEMORY;
 755                 }
 756 
 757                 incoming.previous = talloc(mem_ctx, struct AuthenticationInformationArray);
 758                 if (!incoming.previous) {
 759                         return NT_STATUS_NO_MEMORY;
 760                 }
 761                 incoming.previous->array = talloc_array(mem_ctx, struct AuthenticationInformation, incoming.count);
 762                 if (!incoming.previous->array) {
 763                         return NT_STATUS_NO_MEMORY;
 764                 }
 765 
 766                 for (i = 0; i < incoming.count; i++) {
 767                         incoming.previous->array[i].LastUpdateTime = 0;
 768                         incoming.previous->array[i].AuthType = 0;
 769                 }
 770                 ndr_err = ndr_push_struct_blob(&trustAuthIncoming, mem_ctx, 
 771                                                lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx),
 772                                                &incoming,
 773                                                (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob);
 774                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
 775                         return NT_STATUS_INVALID_PARAMETER;
 776                 }
 777         } else {
 778                 trustAuthIncoming = data_blob(NULL, 0);
 779         }
 780         
 781         if (auth_struct.outgoing.count) {
 782                 int i;
 783                 struct trustAuthInOutBlob outgoing;
 784                 
 785                 outgoing.count = auth_struct.outgoing.count;
 786                 outgoing.current = talloc(mem_ctx, struct AuthenticationInformationArray);
 787                 if (!outgoing.current) {
 788                         return NT_STATUS_NO_MEMORY;
 789                 }
 790                 
 791                 outgoing.current->array = *auth_struct.outgoing.current;
 792                 if (!outgoing.current->array) {
 793                         return NT_STATUS_NO_MEMORY;
 794                 }
 795 
 796                 outgoing.previous = talloc(mem_ctx, struct AuthenticationInformationArray);
 797                 if (!outgoing.previous) {
 798                         return NT_STATUS_NO_MEMORY;
 799                 }
 800                 outgoing.previous->array = talloc_array(mem_ctx, struct AuthenticationInformation, outgoing.count);
 801                 if (!outgoing.previous->array) {
 802                         return NT_STATUS_NO_MEMORY;
 803                 }
 804 
 805                 for (i = 0; i < outgoing.count; i++) {
 806                         outgoing.previous->array[i].LastUpdateTime = 0;
 807                         outgoing.previous->array[i].AuthType = 0;
 808                 }
 809                 ndr_err = ndr_push_struct_blob(&trustAuthOutgoing, mem_ctx, 
 810                                                lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx),
 811                                                &outgoing,
 812                                                (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob);
 813                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
 814                         return NT_STATUS_INVALID_PARAMETER;
 815                 }
 816         } else {
 817                 trustAuthOutgoing = data_blob(NULL, 0);
 818         }
 819 
 820         ret = ldb_transaction_start(policy_state->sam_ldb);
 821         if (ret != LDB_SUCCESS) {
 822                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
 823         }
 824 
 825         if (dns_name) {
 826                 char *dns_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
 827                 char *netbios_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
 828                 /* search for the trusted_domain record */
 829                 ret = gendb_search(policy_state->sam_ldb,
 830                                    mem_ctx, policy_state->system_dn, &msgs, attrs,
 831                                    "(&(|(flatname=%s)(cn=%s)(trustPartner=%s)(flatname=%s)(cn=%s)(trustPartner=%s))(objectclass=trustedDomain))", 
 832                                    dns_encoded, dns_encoded, dns_encoded, netbios_encoded, netbios_encoded, netbios_encoded);
 833                 if (ret > 0) {
 834                         ldb_transaction_cancel(policy_state->sam_ldb);
 835                         return NT_STATUS_OBJECT_NAME_COLLISION;
 836                 }
 837         } else {
 838                 char *netbios_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
 839                 /* search for the trusted_domain record */
 840                 ret = gendb_search(policy_state->sam_ldb,
 841                                    mem_ctx, policy_state->system_dn, &msgs, attrs,
 842                                    "(&(|(flatname=%s)(cn=%s)(trustPartner=%s))(objectclass=trustedDomain))", 
 843                                    netbios_encoded, netbios_encoded, netbios_encoded);
 844                 if (ret > 0) {
 845                         ldb_transaction_cancel(policy_state->sam_ldb);
 846                         return NT_STATUS_OBJECT_NAME_COLLISION;
 847                 }
 848         }
 849         
 850         if (ret < 0 ) {
 851                 ldb_transaction_cancel(policy_state->sam_ldb);
 852                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
 853         }
 854         
 855         name = dns_name ? dns_name : netbios_name;
 856 
 857         msg = ldb_msg_new(mem_ctx);
 858         if (msg == NULL) {
 859                 return NT_STATUS_NO_MEMORY;
 860         }
 861 
 862         msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
 863         if ( ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name)) {
 864                         ldb_transaction_cancel(policy_state->sam_ldb);
 865                 return NT_STATUS_NO_MEMORY;
 866         }
 867         
 868         samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "flatname", netbios_name);
 869 
 870         if (r->in.info->sid) {
 871                 const char *sid_string = dom_sid_string(mem_ctx, r->in.info->sid);
 872                 if (!sid_string) {
 873                         ldb_transaction_cancel(policy_state->sam_ldb);
 874                         return NT_STATUS_NO_MEMORY;
 875                 }
 876                         
 877                 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "securityIdentifier", sid_string);
 878         }
 879 
 880         samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "objectClass", "trustedDomain");
 881 
 882         samdb_msg_add_int(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "trustType", r->in.info->trust_type);
 883 
 884         samdb_msg_add_int(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "trustAttributes", r->in.info->trust_attributes);
 885 
 886         samdb_msg_add_int(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "trustDirection", r->in.info->trust_direction);
 887         
 888         if (dns_name) {
 889                 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "trustPartner", dns_name);
 890         }
 891 
 892         if (trustAuthIncoming.data) {
 893                 ret = ldb_msg_add_value(msg, "trustAuthIncoming", &trustAuthIncoming, NULL);
 894                 if (ret != LDB_SUCCESS) {
 895                         ldb_transaction_cancel(policy_state->sam_ldb);
 896                         return NT_STATUS_NO_MEMORY;
 897                 }
 898         }
 899         if (trustAuthOutgoing.data) {
 900                 ret = ldb_msg_add_value(msg, "trustAuthOutgoing", &trustAuthOutgoing, NULL);
 901                 if (ret != LDB_SUCCESS) {
 902                         ldb_transaction_cancel(policy_state->sam_ldb);
 903                         return NT_STATUS_NO_MEMORY;
 904                 }
 905         }
 906 
 907         trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msg->dn);
 908 
 909         /* create the trusted_domain */
 910         ret = ldb_add(trusted_domain_state->policy->sam_ldb, msg);
 911         switch (ret) {
 912         case  LDB_SUCCESS:
 913                 break;
 914         case  LDB_ERR_ENTRY_ALREADY_EXISTS:
 915                 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
 916                 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
 917                          ldb_dn_get_linearized(msg->dn),
 918                          ldb_errstring(trusted_domain_state->policy->sam_ldb)));
 919                 return NT_STATUS_DOMAIN_EXISTS;
 920         case  LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
 921                 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
 922                 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
 923                          ldb_dn_get_linearized(msg->dn),
 924                          ldb_errstring(trusted_domain_state->policy->sam_ldb)));
 925                 return NT_STATUS_ACCESS_DENIED;
 926         default:
 927                 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
 928                 DEBUG(0,("Failed to create user record %s: %s\n",
 929                          ldb_dn_get_linearized(msg->dn),
 930                          ldb_errstring(trusted_domain_state->policy->sam_ldb)));
 931                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
 932         }
 933 
 934         if (r->in.info->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
 935                 msg_user = ldb_msg_new(mem_ctx);
 936                 if (msg_user == NULL) {
 937                         ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
 938                         return NT_STATUS_NO_MEMORY;
 939                 }
 940 
 941                 /* Inbound trusts must also create a cn=users object to match */
 942 
 943                 trusted_domain_state->trusted_domain_user_dn = msg_user->dn
 944                         = ldb_dn_copy(trusted_domain_state, policy_state->domain_dn);
 945                 if ( ! ldb_dn_add_child_fmt(msg_user->dn, "cn=users")) {
 946                         ldb_transaction_cancel(policy_state->sam_ldb);
 947                         return NT_STATUS_NO_MEMORY;
 948                 }
 949         
 950                 if ( ! ldb_dn_add_child_fmt(msg_user->dn, "cn=%s", netbios_name)) {
 951                         ldb_transaction_cancel(policy_state->sam_ldb);
 952                         return NT_STATUS_NO_MEMORY;
 953                 }
 954 
 955                 ldb_msg_add_string(msg_user, "objectClass", "user");
 956 
 957                 ldb_msg_add_steal_string(msg_user, "samAccountName", 
 958                                          talloc_asprintf(mem_ctx, "%s$", netbios_name));
 959 
 960                 if (samdb_msg_add_uint(trusted_domain_state->policy->sam_ldb, mem_ctx, msg_user, 
 961                                        "userAccountControl", 
 962                                        UF_INTERDOMAIN_TRUST_ACCOUNT) != 0) { 
 963                         ldb_transaction_cancel(policy_state->sam_ldb);
 964                         return NT_STATUS_NO_MEMORY; 
 965                 }
 966 
 967                 if (auth_struct.incoming.count) {
 968                         int i;
 969                         for (i=0; i < auth_struct.incoming.count; i++ ) {
 970                                 if (auth_struct.incoming.current[i]->AuthType == TRUST_AUTH_TYPE_NT4OWF) {
 971                                         samdb_msg_add_hash(trusted_domain_state->policy->sam_ldb, 
 972                                                            mem_ctx, msg_user, "unicodePwd", 
 973                                                            &auth_struct.incoming.current[i]->AuthInfo.nt4owf.password);
 974                                 } else if (auth_struct.incoming.current[i]->AuthType == TRUST_AUTH_TYPE_CLEAR) {
 975                                         DATA_BLOB new_password = data_blob_const(auth_struct.incoming.current[i]->AuthInfo.clear.password,
 976                                                                                  auth_struct.incoming.current[i]->AuthInfo.clear.size);
 977                                         ret = ldb_msg_add_value(msg_user, "clearTextPassword", &new_password, NULL);
 978                                         if (ret != LDB_SUCCESS) {
 979                                                 ldb_transaction_cancel(policy_state->sam_ldb);
 980                                                 return NT_STATUS_NO_MEMORY;
 981                                         }
 982                                 } 
 983                         }
 984                 }
 985 
 986                 /* create the cn=users trusted_domain account */
 987                 ret = ldb_add(trusted_domain_state->policy->sam_ldb, msg_user);
 988                 switch (ret) {
 989                 case  LDB_SUCCESS:
 990                         break;
 991                 case  LDB_ERR_ENTRY_ALREADY_EXISTS:
 992                         ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
 993                         DEBUG(0,("Failed to create trusted domain record %s: %s\n",
 994                                  ldb_dn_get_linearized(msg_user->dn),
 995                                  ldb_errstring(trusted_domain_state->policy->sam_ldb)));
 996                         return NT_STATUS_DOMAIN_EXISTS;
 997                 case  LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
 998                         ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
 999                         DEBUG(0,("Failed to create trusted domain record %s: %s\n",
1000                                  ldb_dn_get_linearized(msg_user->dn),
1001                                  ldb_errstring(trusted_domain_state->policy->sam_ldb)));
1002                         return NT_STATUS_ACCESS_DENIED;
1003                 default:
1004                         ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
1005                         DEBUG(0,("Failed to create user record %s: %s\n",
1006                                  ldb_dn_get_linearized(msg_user->dn),
1007                                  ldb_errstring(trusted_domain_state->policy->sam_ldb)));
1008                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
1009                 }
1010         }
1011 
1012         ret = ldb_transaction_commit(policy_state->sam_ldb);
1013         if (ret != LDB_SUCCESS) {
1014                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1015         }
1016 
1017         handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
1018         if (!handle) {
1019                 return NT_STATUS_NO_MEMORY;
1020         }
1021         
1022         handle->data = talloc_steal(handle, trusted_domain_state);
1023         
1024         trusted_domain_state->access_mask = r->in.access_mask;
1025         trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1026         
1027         *r->out.trustdom_handle = handle->wire_handle;
1028         
1029         return NT_STATUS_OK;
1030 }
1031 
1032 /*
1033   lsa_CreateTrustedDomainEx2
1034 */
1035 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx2(struct dcesrv_call_state *dce_call,
     /* [<][>][^][v][top][bottom][index][help] */
1036                                            TALLOC_CTX *mem_ctx,
1037                                            struct lsa_CreateTrustedDomainEx2 *r)
1038 {
1039         return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, r, NDR_LSA_CREATETRUSTEDDOMAINEX2);
1040 }
1041 /*
1042   lsa_CreateTrustedDomainEx
1043 */
1044 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx(struct dcesrv_call_state *dce_call,
     /* [<][>][^][v][top][bottom][index][help] */
1045                                           TALLOC_CTX *mem_ctx,
1046                                           struct lsa_CreateTrustedDomainEx *r)
1047 {
1048         struct lsa_CreateTrustedDomainEx2 r2;
1049 
1050         r2.in.policy_handle = r->in.policy_handle;
1051         r2.in.info = r->in.info;
1052         r2.in.auth_info = r->in.auth_info;
1053         r2.out.trustdom_handle = r->out.trustdom_handle;
1054         return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, &r2, NDR_LSA_CREATETRUSTEDDOMAINEX);
1055 }
1056 
1057 /* 
1058   lsa_CreateTrustedDomain 
1059 */
1060 static NTSTATUS dcesrv_lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
1061                                         struct lsa_CreateTrustedDomain *r)
1062 {
1063         struct lsa_CreateTrustedDomainEx2 r2;
1064 
1065         r2.in.policy_handle = r->in.policy_handle;
1066         r2.in.info = talloc(mem_ctx, struct lsa_TrustDomainInfoInfoEx);
1067         if (!r2.in.info) {
1068                 return NT_STATUS_NO_MEMORY;
1069         }
1070 
1071         r2.in.info->domain_name.string = NULL;
1072         r2.in.info->netbios_name = r->in.info->name;
1073         r2.in.info->sid = r->in.info->sid;
1074         r2.in.info->trust_direction = LSA_TRUST_DIRECTION_OUTBOUND;
1075         r2.in.info->trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
1076         r2.in.info->trust_attributes = 0;
1077         
1078         r2.in.access_mask = r->in.access_mask;
1079         r2.out.trustdom_handle = r->out.trustdom_handle;
1080 
1081         return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, &r2, NDR_LSA_CREATETRUSTEDDOMAIN);
1082                          
1083 }
1084 
1085 /* 
1086   lsa_OpenTrustedDomain
1087 */
1088 static NTSTATUS dcesrv_lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
1089                                       struct lsa_OpenTrustedDomain *r)
1090 {
1091         struct dcesrv_handle *policy_handle;
1092         
1093         struct lsa_policy_state *policy_state;
1094         struct lsa_trusted_domain_state *trusted_domain_state;
1095         struct dcesrv_handle *handle;
1096         struct ldb_message **msgs;
1097         const char *attrs[] = {
1098                 "trustDirection",
1099                 "flatname",
1100                 NULL
1101         };
1102 
1103         const char *sid_string;
1104         int ret;
1105 
1106         DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1107         ZERO_STRUCTP(r->out.trustdom_handle);
1108         policy_state = policy_handle->data;
1109 
1110         trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
1111         if (!trusted_domain_state) {
1112                 return NT_STATUS_NO_MEMORY;
1113         }
1114         trusted_domain_state->policy = policy_state;
1115 
1116         sid_string = dom_sid_string(mem_ctx, r->in.sid);
1117         if (!sid_string) {
1118                 return NT_STATUS_NO_MEMORY;
1119         }
1120 
1121         /* search for the trusted_domain record */
1122         ret = gendb_search(trusted_domain_state->policy->sam_ldb,
1123                            mem_ctx, policy_state->system_dn, &msgs, attrs,
1124                            "(&(securityIdentifier=%s)(objectclass=trustedDomain))", 
1125                            sid_string);
1126         if (ret == 0) {
1127                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1128         }
1129         
1130         if (ret != 1) {
1131                 DEBUG(0,("Found %d records matching DN %s\n", ret,
1132                          ldb_dn_get_linearized(policy_state->system_dn)));
1133                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1134         }
1135 
1136         trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
1137 
1138         trusted_domain_state->trusted_domain_user_dn = NULL;
1139 
1140         if (ldb_msg_find_attr_as_int(msgs[0], "trustDirection", 0) & LSA_TRUST_DIRECTION_INBOUND) {
1141                 const char *flatname = ldb_binary_encode_string(mem_ctx, ldb_msg_find_attr_as_string(msgs[0], "flatname", NULL));
1142                 /* search for the trusted_domain record */
1143                 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
1144                                    mem_ctx, policy_state->domain_dn, &msgs, attrs,
1145                                    "(&(samaccountname=%s$)(objectclass=user)(userAccountControl:1.2.840.113556.1.4.803:=%d))", 
1146                                    flatname, UF_INTERDOMAIN_TRUST_ACCOUNT);
1147                 if (ret == 1) {
1148                         trusted_domain_state->trusted_domain_user_dn = talloc_steal(trusted_domain_state, msgs[0]->dn);
1149                 }
1150         }
1151         handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
1152         if (!handle) {
1153                 return NT_STATUS_NO_MEMORY;
1154         }
1155         
1156         handle->data = talloc_steal(handle, trusted_domain_state);
1157         
1158         trusted_domain_state->access_mask = r->in.access_mask;
1159         trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1160         
1161         *r->out.trustdom_handle = handle->wire_handle;
1162         
1163         return NT_STATUS_OK;
1164 }
1165 
1166 
1167 /*
1168   lsa_OpenTrustedDomainByName
1169 */
1170 static NTSTATUS dcesrv_lsa_OpenTrustedDomainByName(struct dcesrv_call_state *dce_call,
     /* [<][>][^][v][top][bottom][index][help] */
1171                                             TALLOC_CTX *mem_ctx,
1172                                             struct lsa_OpenTrustedDomainByName *r)
1173 {
1174         struct dcesrv_handle *policy_handle;
1175         
1176         struct lsa_policy_state *policy_state;
1177         struct lsa_trusted_domain_state *trusted_domain_state;
1178         struct dcesrv_handle *handle;
1179         struct ldb_message **msgs;
1180         const char *attrs[] = {
1181                 NULL
1182         };
1183 
1184         int ret;
1185 
1186         DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1187         ZERO_STRUCTP(r->out.trustdom_handle);
1188         policy_state = policy_handle->data;
1189 
1190         if (!r->in.name.string) {
1191                 return NT_STATUS_INVALID_PARAMETER;
1192         }
1193         
1194         trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
1195         if (!trusted_domain_state) {
1196                 return NT_STATUS_NO_MEMORY;
1197         }
1198         trusted_domain_state->policy = policy_state;
1199 
1200         /* search for the trusted_domain record */
1201         ret = gendb_search(trusted_domain_state->policy->sam_ldb,
1202                            mem_ctx, policy_state->system_dn, &msgs, attrs,
1203                            "(&(flatname=%s)(objectclass=trustedDomain))", 
1204                            ldb_binary_encode_string(mem_ctx, r->in.name.string));
1205         if (ret == 0) {
1206                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1207         }
1208         
1209         if (ret != 1) {
1210                 DEBUG(0,("Found %d records matching DN %s\n", ret,
1211                          ldb_dn_get_linearized(policy_state->system_dn)));
1212                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1213         }
1214 
1215         trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
1216         
1217         handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
1218         if (!handle) {
1219                 return NT_STATUS_NO_MEMORY;
1220         }
1221         
1222         handle->data = talloc_steal(handle, trusted_domain_state);
1223         
1224         trusted_domain_state->access_mask = r->in.access_mask;
1225         trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1226         
1227         *r->out.trustdom_handle = handle->wire_handle;
1228         
1229         return NT_STATUS_OK;
1230 }
1231 
1232 
1233 
1234 /* 
1235   lsa_SetTrustedDomainInfo
1236 */
1237 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
1238                                          struct lsa_SetTrustedDomainInfo *r)
1239 {
1240         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1241 }
1242 
1243 
1244 
1245 /* 
1246   lsa_SetInfomrationTrustedDomain
1247 */
1248 static NTSTATUS dcesrv_lsa_SetInformationTrustedDomain(struct dcesrv_call_state *dce_call, 
     /* [<][>][^][v][top][bottom][index][help] */
1249                                                 TALLOC_CTX *mem_ctx,
1250                                                 struct lsa_SetInformationTrustedDomain *r)
1251 {
1252         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1253 }
1254 
1255 
1256 /* 
1257   lsa_DeleteTrustedDomain
1258 */
1259 static NTSTATUS dcesrv_lsa_DeleteTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
1260                                       struct lsa_DeleteTrustedDomain *r)
1261 {
1262         NTSTATUS status;
1263         struct lsa_OpenTrustedDomain opn;
1264         struct lsa_DeleteObject del;
1265         struct dcesrv_handle *h;
1266 
1267         opn.in.handle = r->in.handle;
1268         opn.in.sid = r->in.dom_sid;
1269         opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1270         opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1271         if (!opn.out.trustdom_handle) {
1272                 return NT_STATUS_NO_MEMORY;
1273         }
1274         status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &opn);
1275         if (!NT_STATUS_IS_OK(status)) {
1276                 return status;
1277         }
1278 
1279         DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
1280         talloc_steal(mem_ctx, h);
1281 
1282         del.in.handle = opn.out.trustdom_handle;
1283         del.out.handle = opn.out.trustdom_handle;
1284         status = dcesrv_lsa_DeleteObject(dce_call, mem_ctx, &del);
1285         if (!NT_STATUS_IS_OK(status)) {
1286                 return status;
1287         }
1288         return NT_STATUS_OK;
1289 }
1290 
1291 static NTSTATUS fill_trust_domain_ex(TALLOC_CTX *mem_ctx, 
     /* [<][>][^][v][top][bottom][index][help] */
1292                                      struct ldb_message *msg, 
1293                                      struct lsa_TrustDomainInfoInfoEx *info_ex) 
1294 {
1295         info_ex->domain_name.string
1296                 = ldb_msg_find_attr_as_string(msg, "trustPartner", NULL);
1297         info_ex->netbios_name.string
1298                 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
1299         info_ex->sid 
1300                 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
1301         info_ex->trust_direction
1302                 = ldb_msg_find_attr_as_int(msg, "trustDirection", 0);
1303         info_ex->trust_type
1304                 = ldb_msg_find_attr_as_int(msg, "trustType", 0);
1305         info_ex->trust_attributes
1306                 = ldb_msg_find_attr_as_int(msg, "trustAttributes", 0);  
1307         return NT_STATUS_OK;
1308 }
1309 
1310 /* 
1311   lsa_QueryTrustedDomainInfo
1312 */
1313 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
1314                                            struct lsa_QueryTrustedDomainInfo *r)
1315 {
1316         union lsa_TrustedDomainInfo *info = NULL;
1317         struct dcesrv_handle *h;
1318         struct lsa_trusted_domain_state *trusted_domain_state;
1319         struct ldb_message *msg;
1320         int ret;
1321         struct ldb_message **res;
1322         const char *attrs[] = {
1323                 "flatname", 
1324                 "trustPartner",
1325                 "securityIdentifier",
1326                 "trustDirection",
1327                 "trustType",
1328                 "trustAttributes", 
1329                 "msDs-supportedEncryptionTypes",
1330                 NULL
1331         };
1332 
1333         DCESRV_PULL_HANDLE(h, r->in.trustdom_handle, LSA_HANDLE_TRUSTED_DOMAIN);
1334 
1335         trusted_domain_state = talloc_get_type(h->data, struct lsa_trusted_domain_state);
1336 
1337         /* pull all the user attributes */
1338         ret = gendb_search_dn(trusted_domain_state->policy->sam_ldb, mem_ctx,
1339                               trusted_domain_state->trusted_domain_dn, &res, attrs);
1340         if (ret != 1) {
1341                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1342         }
1343         msg = res[0];
1344         
1345         info = talloc_zero(mem_ctx, union lsa_TrustedDomainInfo);
1346         if (!info) {
1347                 return NT_STATUS_NO_MEMORY;
1348         }
1349         *r->out.info = info;
1350 
1351         switch (r->in.level) {
1352         case LSA_TRUSTED_DOMAIN_INFO_NAME:
1353                 info->name.netbios_name.string
1354                         = samdb_result_string(msg, "flatname", NULL);                                      
1355                 break;
1356         case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
1357                 info->posix_offset.posix_offset
1358                         = samdb_result_uint(msg, "posixOffset", 0);                                        
1359                 break;
1360 #if 0  /* Win2k3 doesn't implement this */
1361         case LSA_TRUSTED_DOMAIN_INFO_BASIC:
1362                 r->out.info->info_basic.netbios_name.string 
1363                         = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
1364                 r->out.info->info_basic.sid
1365                         = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
1366                 break;
1367 #endif
1368         case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
1369                 return fill_trust_domain_ex(mem_ctx, msg, &info->info_ex);
1370 
1371         case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
1372                 ZERO_STRUCT(info->full_info);
1373                 return fill_trust_domain_ex(mem_ctx, msg, &info->full_info.info_ex);
1374 
1375         case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
1376                 ZERO_STRUCT(info->full_info2_internal);
1377                 info->full_info2_internal.posix_offset.posix_offset
1378                         = samdb_result_uint(msg, "posixOffset", 0);                                        
1379                 return fill_trust_domain_ex(mem_ctx, msg, &info->full_info2_internal.info.info_ex);
1380                 
1381         case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES:
1382                 info->enc_types.enc_types
1383                         = samdb_result_uint(msg, "msDs-supportedEncryptionTypes", KERB_ENCTYPE_RC4_HMAC_MD5);
1384                 break;
1385 
1386         case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
1387         case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
1388                 /* oops, we don't want to return the info after all */
1389                 talloc_free(info);
1390                 *r->out.info = NULL;
1391                 return NT_STATUS_INVALID_PARAMETER;
1392         default:
1393                 /* oops, we don't want to return the info after all */
1394                 talloc_free(info);
1395                 *r->out.info = NULL;
1396                 return NT_STATUS_INVALID_INFO_CLASS;
1397         }
1398 
1399         return NT_STATUS_OK;
1400 }
1401 
1402 
1403 /* 
1404   lsa_QueryTrustedDomainInfoBySid
1405 */
1406 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoBySid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
1407                                                 struct lsa_QueryTrustedDomainInfoBySid *r)
1408 {
1409         NTSTATUS status;
1410         struct lsa_OpenTrustedDomain opn;
1411         struct lsa_QueryTrustedDomainInfo query;
1412         struct dcesrv_handle *h;
1413 
1414         opn.in.handle = r->in.handle;
1415         opn.in.sid = r->in.dom_sid;
1416         opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1417         opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1418         if (!opn.out.trustdom_handle) {
1419                 return NT_STATUS_NO_MEMORY;
1420         }
1421         status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &opn);
1422         if (!NT_STATUS_IS_OK(status)) {
1423                 return status;
1424         }
1425 
1426         /* Ensure this handle goes away at the end of this call */
1427         DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
1428         talloc_steal(mem_ctx, h);
1429 
1430         query.in.trustdom_handle = opn.out.trustdom_handle;
1431         query.in.level = r->in.level;
1432         query.out.info = r->out.info;
1433         status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1434         if (!NT_STATUS_IS_OK(status)) {
1435                 return status;
1436         }
1437 
1438         return NT_STATUS_OK;
1439 }
1440 
1441 /*
1442   lsa_SetTrustedDomainInfoByName
1443 */
1444 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
     /* [<][>][^][v][top][bottom][index][help] */
1445                                                TALLOC_CTX *mem_ctx,
1446                                                struct lsa_SetTrustedDomainInfoByName *r)
1447 {
1448         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1449 }
1450 
1451 /* 
1452    lsa_QueryTrustedDomainInfoByName
1453 */
1454 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
     /* [<][>][^][v][top][bottom][index][help] */
1455                                                  TALLOC_CTX *mem_ctx,
1456                                                  struct lsa_QueryTrustedDomainInfoByName *r)
1457 {
1458         NTSTATUS status;
1459         struct lsa_OpenTrustedDomainByName opn;
1460         struct lsa_QueryTrustedDomainInfo query;
1461         struct dcesrv_handle *h;
1462 
1463         opn.in.handle = r->in.handle;
1464         opn.in.name = *r->in.trusted_domain;
1465         opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1466         opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1467         if (!opn.out.trustdom_handle) {
1468                 return NT_STATUS_NO_MEMORY;
1469         }
1470         status = dcesrv_lsa_OpenTrustedDomainByName(dce_call, mem_ctx, &opn);
1471         if (!NT_STATUS_IS_OK(status)) {
1472                 return status;
1473         }
1474         
1475         /* Ensure this handle goes away at the end of this call */
1476         DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
1477         talloc_steal(mem_ctx, h);
1478 
1479         query.in.trustdom_handle = opn.out.trustdom_handle;
1480         query.in.level = r->in.level;
1481         query.out.info = r->out.info;
1482         status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1483         if (!NT_STATUS_IS_OK(status)) {
1484                 return status;
1485         }
1486         
1487         return NT_STATUS_OK;
1488 }
1489 
1490 /*
1491   lsa_CloseTrustedDomainEx 
1492 */
1493 static NTSTATUS dcesrv_lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
     /* [<][>][^][v][top][bottom][index][help] */
1494                                          TALLOC_CTX *mem_ctx,
1495                                          struct lsa_CloseTrustedDomainEx *r)
1496 {
1497         /* The result of a bad hair day from an IDL programmer?  Not
1498          * implmented in Win2k3.  You should always just lsa_Close
1499          * anyway. */
1500         return NT_STATUS_NOT_IMPLEMENTED;
1501 }
1502 
1503 
1504 /*
1505   comparison function for sorting lsa_DomainInformation array
1506 */
1507 static int compare_DomainInfo(struct lsa_DomainInfo *e1, struct lsa_DomainInfo *e2)
     /* [<][>][^][v][top][bottom][index][help] */
1508 {
1509         return strcasecmp_m(e1->name.string, e2->name.string);
1510 }
1511 
1512 /* 
1513   lsa_EnumTrustDom 
1514 */
1515 static NTSTATUS dcesrv_lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
1516                                  struct lsa_EnumTrustDom *r)
1517 {
1518         struct dcesrv_handle *policy_handle;
1519         struct lsa_DomainInfo *entries;
1520         struct lsa_policy_state *policy_state;
1521         struct ldb_message **domains;
1522         const char *attrs[] = {
1523                 "flatname", 
1524                 "securityIdentifier",
1525                 NULL
1526         };
1527 
1528 
1529         int count, i;
1530 
1531         *r->out.resume_handle = 0;
1532 
1533         r->out.domains->domains = NULL;
1534         r->out.domains->count = 0;
1535 
1536         DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1537 
1538         policy_state = policy_handle->data;
1539 
1540         /* search for all users in this domain. This could possibly be cached and 
1541            resumed based on resume_key */
1542         count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs, 
1543                              "objectclass=trustedDomain");
1544         if (count == -1) {
1545                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1546         }
1547 
1548         /* convert to lsa_TrustInformation format */
1549         entries = talloc_array(mem_ctx, struct lsa_DomainInfo, count);
1550         if (!entries) {
1551                 return NT_STATUS_NO_MEMORY;
1552         }
1553         for (i=0;i<count;i++) {
1554                 entries[i].sid = samdb_result_dom_sid(mem_ctx, domains[i], "securityIdentifier");
1555                 entries[i].name.string = samdb_result_string(domains[i], "flatname", NULL);
1556         }
1557 
1558         /* sort the results by name */
1559         qsort(entries, count, sizeof(*entries), 
1560               (comparison_fn_t)compare_DomainInfo);
1561 
1562         if (*r->in.resume_handle >= count) {
1563                 *r->out.resume_handle = -1;
1564 
1565                 return NT_STATUS_NO_MORE_ENTRIES;
1566         }
1567 
1568         /* return the rest, limit by max_size. Note that we 
1569            use the w2k3 element size value of 60 */
1570         r->out.domains->count = count - *r->in.resume_handle;
1571         r->out.domains->count = MIN(r->out.domains->count, 
1572                                  1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
1573 
1574         r->out.domains->domains = entries + *r->in.resume_handle;
1575         r->out.domains->count = r->out.domains->count;
1576 
1577         if (r->out.domains->count < count - *r->in.resume_handle) {
1578                 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1579                 return STATUS_MORE_ENTRIES;
1580         }
1581 
1582         return NT_STATUS_OK;
1583 }
1584 
1585 /*
1586   comparison function for sorting lsa_DomainInformation array
1587 */
1588 static int compare_TrustDomainInfoInfoEx(struct lsa_TrustDomainInfoInfoEx *e1, struct lsa_TrustDomainInfoInfoEx *e2)
     /* [<][>][^][v][top][bottom][index][help] */
1589 {
1590         return strcasecmp_m(e1->netbios_name.string, e2->netbios_name.string);
1591 }
1592 
1593 /* 
1594   lsa_EnumTrustedDomainsEx 
1595 */
1596 static NTSTATUS dcesrv_lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
1597                                         struct lsa_EnumTrustedDomainsEx *r)
1598 {
1599         struct dcesrv_handle *policy_handle;
1600         struct lsa_TrustDomainInfoInfoEx *entries;
1601         struct lsa_policy_state *policy_state;
1602         struct ldb_message **domains;
1603         const char *attrs[] = {
1604                 "flatname", 
1605                 "trustPartner",
1606                 "securityIdentifier",
1607                 "trustDirection",
1608                 "trustType",
1609                 "trustAttributes", 
1610                 NULL
1611         };
1612         NTSTATUS nt_status;
1613 
1614         int count, i;
1615 
1616         *r->out.resume_handle = 0;
1617 
1618         r->out.domains->domains = NULL;
1619         r->out.domains->count = 0;
1620 
1621         DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1622 
1623         policy_state = policy_handle->data;
1624 
1625         /* search for all users in this domain. This could possibly be cached and 
1626            resumed based on resume_key */
1627         count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs, 
1628                              "objectclass=trustedDomain");
1629         if (count == -1) {
1630                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1631         }
1632 
1633         /* convert to lsa_DomainInformation format */
1634         entries = talloc_array(mem_ctx, struct lsa_TrustDomainInfoInfoEx, count);
1635         if (!entries) {
1636                 return NT_STATUS_NO_MEMORY;
1637         }
1638         for (i=0;i<count;i++) {
1639                 nt_status = fill_trust_domain_ex(mem_ctx, domains[i], &entries[i]);
1640                 if (!NT_STATUS_IS_OK(nt_status)) {
1641                         return nt_status;
1642                 }
1643         }
1644 
1645         /* sort the results by name */
1646         qsort(entries, count, sizeof(*entries), 
1647               (comparison_fn_t)compare_TrustDomainInfoInfoEx);
1648 
1649         if (*r->in.resume_handle >= count) {
1650                 *r->out.resume_handle = -1;
1651 
1652                 return NT_STATUS_NO_MORE_ENTRIES;
1653         }
1654 
1655         /* return the rest, limit by max_size. Note that we 
1656            use the w2k3 element size value of 60 */
1657         r->out.domains->count = count - *r->in.resume_handle;
1658         r->out.domains->count = MIN(r->out.domains->count, 
1659                                  1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
1660 
1661         r->out.domains->domains = entries + *r->in.resume_handle;
1662         r->out.domains->count = r->out.domains->count;
1663 
1664         if (r->out.domains->count < count - *r->in.resume_handle) {
1665                 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1666                 return STATUS_MORE_ENTRIES;
1667         }
1668 
1669         return NT_STATUS_OK;
1670 }
1671 
1672 
1673 /* 
1674   lsa_OpenAccount 
1675 */
1676 static NTSTATUS dcesrv_lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
1677                                 struct lsa_OpenAccount *r)
1678 {
1679         struct dcesrv_handle *h, *ah;
1680         struct lsa_policy_state *state;
1681         struct lsa_account_state *astate;
1682 
1683         ZERO_STRUCTP(r->out.acct_handle);
1684 
1685         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1686 
1687         state = h->data;
1688 
1689         astate = talloc(dce_call->conn, struct lsa_account_state);
1690         if (astate == NULL) {
1691                 return NT_STATUS_NO_MEMORY;
1692         }
1693 
1694         astate->account_sid = dom_sid_dup(astate, r->in.sid);
1695         if (astate->account_sid == NULL) {
1696                 talloc_free(astate);
1697                 return NT_STATUS_NO_MEMORY;
1698         }
1699         
1700         astate->policy = talloc_reference(astate, state);
1701         astate->access_mask = r->in.access_mask;
1702 
1703         ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
1704         if (!ah) {
1705                 talloc_free(astate);
1706                 return NT_STATUS_NO_MEMORY;
1707         }
1708 
1709         ah->data = talloc_steal(ah, astate);
1710 
1711         *r->out.acct_handle = ah->wire_handle;
1712 
1713         return NT_STATUS_OK;
1714 }
1715 
1716 
1717 /* 
1718   lsa_EnumPrivsAccount 
1719 */
1720 static NTSTATUS dcesrv_lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call, 
     /* [<][>][^][v][top][bottom][index][help] */
1721                                      TALLOC_CTX *mem_ctx,
1722                                      struct lsa_EnumPrivsAccount *r)
1723 {
1724         struct dcesrv_handle *h;
1725         struct lsa_account_state *astate;
1726         int ret, i;
1727         struct ldb_message **res;
1728         const char * const attrs[] = { "privilege", NULL};
1729         struct ldb_message_element *el;
1730         const char *sidstr;
1731         struct lsa_PrivilegeSet *privs;
1732 
1733         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1734 
1735         astate = h->data;
1736 
1737         privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
1738         if (privs == NULL) {
1739                 return NT_STATUS_NO_MEMORY;
1740         }
1741         privs->count = 0;
1742         privs->unknown = 0;
1743         privs->set = NULL;
1744 
1745         *r->out.privs = privs;
1746 
1747         sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid);
1748         if (sidstr == NULL) {
1749                 return NT_STATUS_NO_MEMORY;
1750         }
1751 
1752         ret = gendb_search(astate->policy->sam_ldb, mem_ctx, NULL, &res, attrs, 
1753                            "objectSid=%s", sidstr);
1754         if (ret != 1) {
1755                 return NT_STATUS_OK;
1756         }
1757 
1758         el = ldb_msg_find_element(res[0], "privilege");
1759         if (el == NULL || el->num_values == 0) {
1760                 return NT_STATUS_OK;
1761         }
1762 
1763         privs->set = talloc_array(privs,
1764                                   struct lsa_LUIDAttribute, el->num_values);
1765         if (privs->set == NULL) {
1766                 return NT_STATUS_NO_MEMORY;
1767         }
1768 
1769         for (i=0;i<el->num_values;i++) {
1770                 int id = sec_privilege_id((const char *)el->values[i].data);
1771                 if (id == -1) {
1772                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
1773                 }
1774                 privs->set[i].attribute = 0;
1775                 privs->set[i].luid.low = id;
1776                 privs->set[i].luid.high = 0;
1777         }
1778 
1779         privs->count = el->num_values;
1780 
1781         return NT_STATUS_OK;
1782 }
1783 
1784 /* 
1785   lsa_EnumAccountRights 
1786 */
1787 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call, 
     /* [<][>][^][v][top][bottom][index][help] */
1788                                       TALLOC_CTX *mem_ctx,
1789                                       struct lsa_EnumAccountRights *r)
1790 {
1791         struct dcesrv_handle *h;
1792         struct lsa_policy_state *state;
1793         int ret, i;
1794         struct ldb_message **res;
1795         const char * const attrs[] = { "privilege", NULL};
1796         const char *sidstr;
1797         struct ldb_message_element *el;
1798 
1799         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1800 
1801         state = h->data;
1802 
1803         sidstr = ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid);
1804         if (sidstr == NULL) {
1805                 return NT_STATUS_NO_MEMORY;
1806         }
1807 
1808         ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs, 
1809                            "(&(objectSid=%s)(privilege=*))", sidstr);
1810         if (ret == 0) {
1811                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1812         }
1813         if (ret > 1) {
1814                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1815         }
1816         if (ret == -1) {
1817                 DEBUG(3, ("searching for account rights for SID: %s failed: %s", 
1818                           dom_sid_string(mem_ctx, r->in.sid),
1819                           ldb_errstring(state->sam_ldb)));
1820                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1821         }
1822 
1823         el = ldb_msg_find_element(res[0], "privilege");
1824         if (el == NULL || el->num_values == 0) {
1825                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1826         }
1827 
1828         r->out.rights->count = el->num_values;
1829         r->out.rights->names = talloc_array(r->out.rights, 
1830                                             struct lsa_StringLarge, r->out.rights->count);
1831         if (r->out.rights->names == NULL) {
1832                 return NT_STATUS_NO_MEMORY;
1833         }
1834 
1835         for (i=0;i<el->num_values;i++) {
1836                 r->out.rights->names[i].string = (const char *)el->values[i].data;
1837         }
1838 
1839         return NT_STATUS_OK;
1840 }
1841 
1842 
1843 
1844 /* 
1845   helper for lsa_AddAccountRights and lsa_RemoveAccountRights
1846 */
1847 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call, 
     /* [<][>][^][v][top][bottom][index][help] */
1848                                            TALLOC_CTX *mem_ctx,
1849                                            struct lsa_policy_state *state,
1850                                            int ldb_flag,
1851                                            struct dom_sid *sid,
1852                                            const struct lsa_RightSet *rights)
1853 {
1854         const char *sidstr;
1855         struct ldb_message *msg;
1856         struct ldb_message_element *el;
1857         int i, ret;
1858         struct lsa_EnumAccountRights r2;
1859 
1860         sidstr = ldap_encode_ndr_dom_sid(mem_ctx, sid);
1861         if (sidstr == NULL) {
1862                 return NT_STATUS_NO_MEMORY;
1863         }
1864 
1865         msg = ldb_msg_new(mem_ctx);
1866         if (msg == NULL) {
1867                 return NT_STATUS_NO_MEMORY;
1868         }
1869 
1870         msg->dn = samdb_search_dn(state->sam_ldb, mem_ctx, 
1871                                   NULL, "objectSid=%s", sidstr);
1872         if (msg->dn == NULL) {
1873                 NTSTATUS status;
1874                 if (ldb_flag == LDB_FLAG_MOD_DELETE) {
1875                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1876                 }
1877                 status = samdb_create_foreign_security_principal(state->sam_ldb, mem_ctx, 
1878                                                                  sid, &msg->dn);
1879                 if (!NT_STATUS_IS_OK(status)) {
1880                         return status;
1881                 }
1882                 return NT_STATUS_NO_SUCH_USER;
1883         }
1884 
1885         if (ldb_msg_add_empty(msg, "privilege", ldb_flag, NULL)) {
1886                 return NT_STATUS_NO_MEMORY;
1887         }
1888 
1889         if (ldb_flag == LDB_FLAG_MOD_ADD) {
1890                 NTSTATUS status;
1891 
1892                 r2.in.handle = &state->handle->wire_handle;
1893                 r2.in.sid = sid;
1894                 r2.out.rights = talloc(mem_ctx, struct lsa_RightSet);
1895 
1896                 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1897                 if (!NT_STATUS_IS_OK(status)) {
1898                         ZERO_STRUCTP(r2.out.rights);
1899                 }
1900         }
1901 
1902         for (i=0;i<rights->count;i++) {
1903                 if (sec_privilege_id(rights->names[i].string) == -1) {
1904                         return NT_STATUS_NO_SUCH_PRIVILEGE;
1905                 }
1906 
1907                 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1908                         int j;
1909                         for (j=0;j<r2.out.rights->count;j++) {
1910                                 if (strcasecmp_m(r2.out.rights->names[j].string, 
1911                                                rights->names[i].string) == 0) {
1912                                         break;
1913                                 }
1914                         }
1915                         if (j != r2.out.rights->count) continue;
1916                 }
1917 
1918                 ret = ldb_msg_add_string(msg, "privilege", rights->names[i].string);
1919                 if (ret != LDB_SUCCESS) {
1920                         return NT_STATUS_NO_MEMORY;
1921                 }
1922         }
1923 
1924         el = ldb_msg_find_element(msg, "privilege");
1925         if (!el) {
1926                 return NT_STATUS_OK;
1927         }
1928 
1929         ret = ldb_modify(state->sam_ldb, msg);
1930         if (ret != 0) {
1931                 if (ldb_flag == LDB_FLAG_MOD_DELETE && ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
1932                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1933                 }
1934                 DEBUG(3, ("Could not %s attributes from %s: %s", 
1935                           ldb_flag == LDB_FLAG_MOD_DELETE ? "delete" : "add",
1936                           ldb_dn_get_linearized(msg->dn), ldb_errstring(state->sam_ldb)));
1937                 return NT_STATUS_UNEXPECTED_IO_ERROR;
1938         }
1939 
1940         return NT_STATUS_OK;
1941 }
1942 
1943 /* 
1944   lsa_AddPrivilegesToAccount
1945 */
1946 static NTSTATUS dcesrv_lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
1947                                            struct lsa_AddPrivilegesToAccount *r)
1948 {
1949         struct lsa_RightSet rights;
1950         struct dcesrv_handle *h;
1951         struct lsa_account_state *astate;
1952         int i;
1953 
1954         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1955 
1956         astate = h->data;
1957 
1958         rights.count = r->in.privs->count;
1959         rights.names = talloc_array(mem_ctx, struct lsa_StringLarge, rights.count);
1960         if (rights.names == NULL) {
1961                 return NT_STATUS_NO_MEMORY;
1962         }
1963         for (i=0;i<rights.count;i++) {
1964                 int id = r->in.privs->set[i].luid.low;
1965                 if (r->in.privs->set[i].luid.high) {
1966                         return NT_STATUS_NO_SUCH_PRIVILEGE;
1967                 }
1968                 rights.names[i].string = sec_privilege_name(id);
1969                 if (rights.names[i].string == NULL) {
1970                         return NT_STATUS_NO_SUCH_PRIVILEGE;
1971                 }
1972         }
1973 
1974         return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy, 
1975                                           LDB_FLAG_MOD_ADD, astate->account_sid,
1976                                           &rights);
1977 }
1978 
1979 
1980 /* 
1981   lsa_RemovePrivilegesFromAccount
1982 */
1983 static NTSTATUS dcesrv_lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
1984                                                 struct lsa_RemovePrivilegesFromAccount *r)
1985 {
1986         struct lsa_RightSet *rights;
1987         struct dcesrv_handle *h;
1988         struct lsa_account_state *astate;
1989         int i;
1990 
1991         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1992 
1993         astate = h->data;
1994 
1995         rights = talloc(mem_ctx, struct lsa_RightSet);
1996 
1997         if (r->in.remove_all == 1 && 
1998             r->in.privs == NULL) {
1999                 struct lsa_EnumAccountRights r2;
2000                 NTSTATUS status;
2001 
2002                 r2.in.handle = &astate->policy->handle->wire_handle;
2003                 r2.in.sid = astate->account_sid;
2004                 r2.out.rights = rights;
2005 
2006                 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
2007                 if (!NT_STATUS_IS_OK(status)) {
2008                         return status;
2009                 }
2010 
2011                 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy, 
2012                                                   LDB_FLAG_MOD_DELETE, astate->account_sid,
2013                                                   r2.out.rights);
2014         }
2015 
2016         if (r->in.remove_all != 0) {
2017                 return NT_STATUS_INVALID_PARAMETER;
2018         }
2019 
2020         rights->count = r->in.privs->count;
2021         rights->names = talloc_array(mem_ctx, struct lsa_StringLarge, rights->count);
2022         if (rights->names == NULL) {
2023                 return NT_STATUS_NO_MEMORY;
2024         }
2025         for (i=0;i<rights->count;i++) {
2026                 int id = r->in.privs->set[i].luid.low;
2027                 if (r->in.privs->set[i].luid.high) {
2028                         return NT_STATUS_NO_SUCH_PRIVILEGE;
2029                 }
2030                 rights->names[i].string = sec_privilege_name(id);
2031                 if (rights->names[i].string == NULL) {
2032                         return NT_STATUS_NO_SUCH_PRIVILEGE;
2033                 }
2034         }
2035 
2036         return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy, 
2037                                           LDB_FLAG_MOD_DELETE, astate->account_sid,
2038                                           rights);
2039 }
2040 
2041 
2042 /* 
2043   lsa_GetQuotasForAccount
2044 */
2045 static NTSTATUS dcesrv_lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
2046                        struct lsa_GetQuotasForAccount *r)
2047 {
2048         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2049 }
2050 
2051 
2052 /* 
2053   lsa_SetQuotasForAccount
2054 */
2055 static NTSTATUS dcesrv_lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
2056                        struct lsa_SetQuotasForAccount *r)
2057 {
2058         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2059 }
2060 
2061 
2062 /* 
2063   lsa_GetSystemAccessAccount
2064 */
2065 static NTSTATUS dcesrv_lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
2066                        struct lsa_GetSystemAccessAccount *r)
2067 {
2068         int i;
2069         NTSTATUS status;
2070         struct lsa_EnumPrivsAccount enumPrivs;
2071         struct lsa_PrivilegeSet *privs;
2072 
2073         privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
2074         if (!privs) {
2075                 return NT_STATUS_NO_MEMORY;
2076         }
2077         privs->count = 0;
2078         privs->unknown = 0;
2079         privs->set = NULL;
2080 
2081         enumPrivs.in.handle = r->in.handle;
2082         enumPrivs.out.privs = &privs;
2083 
2084         status = dcesrv_lsa_EnumPrivsAccount(dce_call, mem_ctx, &enumPrivs);
2085         if (!NT_STATUS_IS_OK(status)) {
2086                 return status;
2087         }       
2088 
2089         *(r->out.access_mask) = 0x00000000;
2090 
2091         for (i = 0; i < privs->count; i++) {
2092                 int priv = privs->set[i].luid.low;
2093 
2094                 switch (priv) {
2095                 case SEC_PRIV_INTERACTIVE_LOGON:
2096                         *(r->out.access_mask) |= LSA_POLICY_MODE_INTERACTIVE;
2097                         break;
2098                 case SEC_PRIV_NETWORK_LOGON:
2099                         *(r->out.access_mask) |= LSA_POLICY_MODE_NETWORK;
2100                         break;
2101                 case SEC_PRIV_REMOTE_INTERACTIVE_LOGON:
2102                         *(r->out.access_mask) |= LSA_POLICY_MODE_REMOTE_INTERACTIVE;
2103                         break;
2104                 }
2105         }
2106 
2107         return NT_STATUS_OK;
2108 }
2109 
2110 
2111 /* 
2112   lsa_SetSystemAccessAccount
2113 */
2114 static NTSTATUS dcesrv_lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
2115                        struct lsa_SetSystemAccessAccount *r)
2116 {
2117         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2118 }
2119 
2120 
2121 /* 
2122   lsa_CreateSecret 
2123 */
2124 static NTSTATUS dcesrv_lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
2125                                  struct lsa_CreateSecret *r)
2126 {
2127         struct dcesrv_handle *policy_handle;
2128         struct lsa_policy_state *policy_state;
2129         struct lsa_secret_state *secret_state;
2130         struct dcesrv_handle *handle;
2131         struct ldb_message **msgs, *msg;
2132         const char *errstr;
2133         const char *attrs[] = {
2134                 NULL
2135         };
2136 
2137         const char *name;
2138 
2139         int ret;
2140 
2141         DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2142         ZERO_STRUCTP(r->out.sec_handle);
2143         
2144         switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2145         {
2146         case SECURITY_SYSTEM:
2147         case SECURITY_ADMINISTRATOR:
2148                 break;
2149         default:
2150                 /* Users and annonymous are not allowed create secrets */
2151                 return NT_STATUS_ACCESS_DENIED;
2152         }
2153 
2154         policy_state = policy_handle->data;
2155 
2156         if (!r->in.name.string) {
2157                 return NT_STATUS_INVALID_PARAMETER;
2158         }
2159         
2160         secret_state = talloc(mem_ctx, struct lsa_secret_state);
2161         if (!secret_state) {
2162                 return NT_STATUS_NO_MEMORY;
2163         }
2164         secret_state->policy = policy_state;
2165 
2166         msg = ldb_msg_new(mem_ctx);
2167         if (msg == NULL) {
2168                 return NT_STATUS_NO_MEMORY;
2169         }
2170 
2171         if (strncmp("G$", r->in.name.string, 2) == 0) {
2172                 const char *name2;
2173                 name = &r->in.name.string[2];
2174                         /* We need to connect to the database as system, as this is one of the rare RPC calls that must read the secrets (and this is denied otherwise) */
2175                 secret_state->sam_ldb = talloc_reference(secret_state, 
2176                                                          samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(secret_state, dce_call->conn->dce_ctx->lp_ctx))); 
2177                 secret_state->global = true;
2178 
2179                 if (strlen(name) < 1) {
2180                         return NT_STATUS_INVALID_PARAMETER;
2181                 }
2182 
2183                 name2 = talloc_asprintf(mem_ctx, "%s Secret", ldb_binary_encode_string(mem_ctx, name));
2184                 /* search for the secret record */
2185                 ret = gendb_search(secret_state->sam_ldb,
2186                                    mem_ctx, policy_state->system_dn, &msgs, attrs,
2187                                    "(&(cn=%s)(objectclass=secret))", 
2188                                    name2);
2189                 if (ret > 0) {
2190                         return NT_STATUS_OBJECT_NAME_COLLISION;
2191                 }
2192                 
2193                 if (ret == -1) {
2194                         DEBUG(0,("Failure searching for CN=%s: %s\n", 
2195                                  name2, ldb_errstring(secret_state->sam_ldb)));
2196                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
2197                 }
2198 
2199                 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
2200                 if (!name2 || ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name2)) {
2201                         return NT_STATUS_NO_MEMORY;
2202                 }
2203                 
2204                 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name2);
2205         
2206         } else {
2207                 secret_state->global = false;
2208 
2209                 name = r->in.name.string;
2210                 if (strlen(name) < 1) {
2211                         return NT_STATUS_INVALID_PARAMETER;
2212                 }
2213 
2214                 secret_state->sam_ldb = talloc_reference(secret_state, 
2215                                                          secrets_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx));
2216                 /* search for the secret record */
2217                 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2218                                    ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
2219                                    &msgs, attrs,
2220                                    "(&(cn=%s)(objectclass=secret))", 
2221                                    ldb_binary_encode_string(mem_ctx, name));
2222                 if (ret > 0) {
2223                         return NT_STATUS_OBJECT_NAME_COLLISION;
2224                 }
2225                 
2226                 if (ret == -1) {
2227                         DEBUG(0,("Failure searching for CN=%s: %s\n", 
2228                                  name, ldb_errstring(secret_state->sam_ldb)));
2229                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
2230                 }
2231 
2232                 msg->dn = ldb_dn_new_fmt(mem_ctx, secret_state->sam_ldb, "cn=%s,cn=LSA Secrets", name);
2233                 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name);
2234         } 
2235 
2236         /* pull in all the template attributes.  Note this is always from the global samdb */
2237         ret = samdb_copy_template(secret_state->policy->sam_ldb, msg, 
2238                                   "secret", &errstr);
2239         if (ret != 0) {
2240                 DEBUG(0,("Failed to load TemplateSecret from samdb: %s\n",
2241                          errstr));
2242                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2243         }
2244 
2245         samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "objectClass", "secret");
2246         
2247         secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
2248 
2249         /* create the secret */
2250         ret = ldb_add(secret_state->sam_ldb, msg);
2251         if (ret != 0) {
2252                 DEBUG(0,("Failed to create secret record %s: %s\n",
2253                          ldb_dn_get_linearized(msg->dn), 
2254                          ldb_errstring(secret_state->sam_ldb)));
2255                 return NT_STATUS_ACCESS_DENIED;
2256         }
2257 
2258         handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2259         if (!handle) {
2260                 return NT_STATUS_NO_MEMORY;
2261         }
2262         
2263         handle->data = talloc_steal(handle, secret_state);
2264         
2265         secret_state->access_mask = r->in.access_mask;
2266         secret_state->policy = talloc_reference(secret_state, policy_state);
2267         
2268         *r->out.sec_handle = handle->wire_handle;
2269         
2270         return NT_STATUS_OK;
2271 }
2272 
2273 
2274 /* 
2275   lsa_OpenSecret 
2276 */
2277 static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
2278                                struct lsa_OpenSecret *r)
2279 {
2280         struct dcesrv_handle *policy_handle;
2281         
2282         struct lsa_policy_state *policy_state;
2283         struct lsa_secret_state *secret_state;
2284         struct dcesrv_handle *handle;
2285         struct ldb_message **msgs;
2286         const char *attrs[] = {
2287                 NULL
2288         };
2289 
2290         const char *name;
2291 
2292         int ret;
2293 
2294         DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2295         ZERO_STRUCTP(r->out.sec_handle);
2296         policy_state = policy_handle->data;
2297 
2298         if (!r->in.name.string) {
2299                 return NT_STATUS_INVALID_PARAMETER;
2300         }
2301         
2302         switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2303         {
2304         case SECURITY_SYSTEM:
2305         case SECURITY_ADMINISTRATOR:
2306                 break;
2307         default:
2308                 /* Users and annonymous are not allowed to access secrets */
2309                 return NT_STATUS_ACCESS_DENIED;
2310         }
2311 
2312         secret_state = talloc(mem_ctx, struct lsa_secret_state);
2313         if (!secret_state) {
2314                 return NT_STATUS_NO_MEMORY;
2315         }
2316         secret_state->policy = policy_state;
2317 
2318         if (strncmp("G$", r->in.name.string, 2) == 0) {
2319                 name = &r->in.name.string[2];
2320                 /* We need to connect to the database as system, as this is one of the rare RPC calls that must read the secrets (and this is denied otherwise) */
2321                 secret_state->sam_ldb = talloc_reference(secret_state, 
2322                                                          samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(secret_state, dce_call->conn->dce_ctx->lp_ctx))); 
2323                 secret_state->global = true;
2324 
2325                 if (strlen(name) < 1) {
2326                         return NT_STATUS_INVALID_PARAMETER;
2327                 }
2328 
2329                 /* search for the secret record */
2330                 ret = gendb_search(secret_state->sam_ldb,
2331                                    mem_ctx, policy_state->system_dn, &msgs, attrs,
2332                                    "(&(cn=%s Secret)(objectclass=secret))", 
2333                                    ldb_binary_encode_string(mem_ctx, name));
2334                 if (ret == 0) {
2335                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2336                 }
2337                 
2338                 if (ret != 1) {
2339                         DEBUG(0,("Found %d records matching DN %s\n", ret,
2340                                  ldb_dn_get_linearized(policy_state->system_dn)));
2341                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
2342                 }
2343         
2344         } else {
2345                 secret_state->global = false;
2346                 secret_state->sam_ldb = talloc_reference(secret_state, 
2347                                  secrets_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx));
2348 
2349                 name = r->in.name.string;
2350                 if (strlen(name) < 1) {
2351                         return NT_STATUS_INVALID_PARAMETER;
2352                 }
2353 
2354                 /* search for the secret record */
2355                 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2356                                    ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
2357                                    &msgs, attrs,
2358                                    "(&(cn=%s)(objectclass=secret))", 
2359                                    ldb_binary_encode_string(mem_ctx, name));
2360                 if (ret == 0) {
2361                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2362                 }
2363                 
2364                 if (ret != 1) {
2365                         DEBUG(0,("Found %d records matching CN=%s\n", 
2366                                  ret, ldb_binary_encode_string(mem_ctx, name)));
2367                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
2368                 }
2369         } 
2370 
2371         secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
2372         
2373         handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2374         if (!handle) {
2375                 return NT_STATUS_NO_MEMORY;
2376         }
2377         
2378         handle->data = talloc_steal(handle, secret_state);
2379         
2380         secret_state->access_mask = r->in.access_mask;
2381         secret_state->policy = talloc_reference(secret_state, policy_state);
2382         
2383         *r->out.sec_handle = handle->wire_handle;
2384         
2385         return NT_STATUS_OK;
2386 }
2387 
2388 
2389 /* 
2390   lsa_SetSecret 
2391 */
2392 static NTSTATUS dcesrv_lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
2393                               struct lsa_SetSecret *r)
2394 {
2395 
2396         struct dcesrv_handle *h;
2397         struct lsa_secret_state *secret_state;
2398         struct ldb_message *msg;
2399         DATA_BLOB session_key;
2400         DATA_BLOB crypt_secret, secret;
2401         struct ldb_val val;
2402         int ret;
2403         NTSTATUS status = NT_STATUS_OK;
2404 
2405         struct timeval now = timeval_current();
2406         NTTIME nt_now = timeval_to_nttime(&now);
2407 
2408         DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2409 
2410         secret_state = h->data;
2411 
2412         msg = ldb_msg_new(mem_ctx);
2413         if (msg == NULL) {
2414                 return NT_STATUS_NO_MEMORY;
2415         }
2416 
2417         msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);
2418         if (!msg->dn) {
2419                 return NT_STATUS_NO_MEMORY;
2420         }
2421         status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2422         if (!NT_STATUS_IS_OK(status)) {
2423                 return status;
2424         }
2425 
2426         if (r->in.old_val) {
2427                 /* Decrypt */
2428                 crypt_secret.data = r->in.old_val->data;
2429                 crypt_secret.length = r->in.old_val->size;
2430                 
2431                 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2432                 if (!NT_STATUS_IS_OK(status)) {
2433                         return status;
2434                 }
2435                 
2436                 val.data = secret.data;
2437                 val.length = secret.length;
2438                 
2439                 /* set value */
2440                 if (samdb_msg_add_value(secret_state->sam_ldb, 
2441                                         mem_ctx, msg, "priorValue", &val) != 0) {
2442                         return NT_STATUS_NO_MEMORY; 
2443                 }
2444                 
2445                 /* set old value mtime */
2446                 if (samdb_msg_add_uint64(secret_state->sam_ldb, 
2447                                          mem_ctx, msg, "priorSetTime", nt_now) != 0) { 
2448                         return NT_STATUS_NO_MEMORY; 
2449                 }
2450 
2451         } else {
2452                 /* If the old value is not set, then migrate the
2453                  * current value to the old value */
2454                 const struct ldb_val *old_val;
2455                 NTTIME last_set_time;
2456                 struct ldb_message **res;
2457                 const char *attrs[] = {
2458                         "currentValue",
2459                         "lastSetTime",
2460                         NULL
2461                 };
2462                 
2463                 /* search for the secret record */
2464                 ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx,
2465                                       secret_state->secret_dn, &res, attrs);
2466                 if (ret == 0) {
2467                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2468                 }
2469                 
2470                 if (ret != 1) {
2471                         DEBUG(0,("Found %d records matching dn=%s\n", ret,
2472                                  ldb_dn_get_linearized(secret_state->secret_dn)));
2473                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
2474                 }
2475                 
2476                 old_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2477                 last_set_time = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2478                 
2479                 if (old_val) {
2480                         /* set old value */
2481                         if (samdb_msg_add_value(secret_state->sam_ldb, 
2482                                                 mem_ctx, msg, "priorValue", 
2483                                                 old_val) != 0) {
2484                                 return NT_STATUS_NO_MEMORY; 
2485                         }
2486                 } else {
2487                         if (samdb_msg_add_delete(secret_state->sam_ldb, 
2488                                                  mem_ctx, msg, "priorValue")) {
2489                                 return NT_STATUS_NO_MEMORY;
2490                         }
2491                         
2492                 }
2493                 
2494                 /* set old value mtime */
2495                 if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
2496                         if (samdb_msg_add_uint64(secret_state->sam_ldb, 
2497                                                  mem_ctx, msg, "priorSetTime", last_set_time) != 0) { 
2498                                 return NT_STATUS_NO_MEMORY; 
2499                         }
2500                 } else {
2501                         if (samdb_msg_add_uint64(secret_state->sam_ldb, 
2502                                                  mem_ctx, msg, "priorSetTime", nt_now) != 0) { 
2503                                 return NT_STATUS_NO_MEMORY; 
2504                         }
2505                 }
2506         }
2507 
2508         if (r->in.new_val) {
2509                 /* Decrypt */
2510                 crypt_secret.data = r->in.new_val->data;
2511                 crypt_secret.length = r->in.new_val->size;
2512                 
2513                 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2514                 if (!NT_STATUS_IS_OK(status)) {
2515                         return status;
2516                 }
2517                 
2518                 val.data = secret.data;
2519                 val.length = secret.length;
2520                 
2521                 /* set value */
2522                 if (samdb_msg_add_value(secret_state->sam_ldb, 
2523                                         mem_ctx, msg, "currentValue", &val) != 0) {
2524                         return NT_STATUS_NO_MEMORY; 
2525                 }
2526                 
2527                 /* set new value mtime */
2528                 if (samdb_msg_add_uint64(secret_state->sam_ldb, 
2529                                          mem_ctx, msg, "lastSetTime", nt_now) != 0) { 
2530                         return NT_STATUS_NO_MEMORY; 
2531                 }
2532                 
2533         } else {
2534                 /* NULL out the NEW value */
2535                 if (samdb_msg_add_uint64(secret_state->sam_ldb, 
2536                                          mem_ctx, msg, "lastSetTime", nt_now) != 0) { 
2537                         return NT_STATUS_NO_MEMORY; 
2538                 }
2539                 if (samdb_msg_add_delete(secret_state->sam_ldb, 
2540                                          mem_ctx, msg, "currentValue")) {
2541                         return NT_STATUS_NO_MEMORY;
2542                 }
2543         }
2544 
2545         /* modify the samdb record */
2546         ret = samdb_replace(secret_state->sam_ldb, mem_ctx, msg);
2547         if (ret != 0) {
2548                 /* we really need samdb.c to return NTSTATUS */
2549                 return NT_STATUS_UNSUCCESSFUL;
2550         }
2551 
2552         return NT_STATUS_OK;
2553 }
2554 
2555 
2556 /* 
2557   lsa_QuerySecret 
2558 */
2559 static NTSTATUS dcesrv_lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
2560                                 struct lsa_QuerySecret *r)
2561 {
2562         struct dcesrv_handle *h;
2563         struct lsa_secret_state *secret_state;
2564         struct ldb_message *msg;
2565         DATA_BLOB session_key;
2566         DATA_BLOB crypt_secret, secret;
2567         int ret;
2568         struct ldb_message **res;
2569         const char *attrs[] = {
2570                 "currentValue",
2571                 "priorValue",
2572                 "lastSetTime",
2573                 "priorSetTime", 
2574                 NULL
2575         };
2576 
2577         NTSTATUS nt_status;
2578 
2579         DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2580 
2581         /* Ensure user is permitted to read this... */
2582         switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2583         {
2584         case SECURITY_SYSTEM:
2585         case SECURITY_ADMINISTRATOR:
2586                 break;
2587         default:
2588                 /* Users and annonymous are not allowed to read secrets */
2589                 return NT_STATUS_ACCESS_DENIED;
2590         }
2591 
2592         secret_state = h->data;
2593 
2594         /* pull all the user attributes */
2595         ret = gendb_search_dn(secret_state->sam_ldb, mem_ctx,
2596                               secret_state->secret_dn, &res, attrs);
2597         if (ret != 1) {
2598                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2599         }
2600         msg = res[0];
2601         
2602         nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2603         if (!NT_STATUS_IS_OK(nt_status)) {
2604                 return nt_status;
2605         }
2606         
2607         if (r->in.old_val) {
2608                 const struct ldb_val *prior_val;
2609                 r->out.old_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2610                 if (!r->out.old_val) {
2611                         return NT_STATUS_NO_MEMORY;
2612                 }
2613                 prior_val = ldb_msg_find_ldb_val(res[0], "priorValue");
2614                 
2615                 if (prior_val && prior_val->length) {
2616                         secret.data = prior_val->data;
2617                         secret.length = prior_val->length;
2618                 
2619                         /* Encrypt */
2620                         crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2621                         if (!crypt_secret.length) {
2622                                 return NT_STATUS_NO_MEMORY;
2623                         }
2624                         r->out.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2625                         if (!r->out.old_val->buf) {
2626                                 return NT_STATUS_NO_MEMORY;
2627                         }
2628                         r->out.old_val->buf->size = crypt_secret.length;
2629                         r->out.old_val->buf->length = crypt_secret.length;
2630                         r->out.old_val->buf->data = crypt_secret.data;
2631                 }
2632         }
2633         
2634         if (r->in.old_mtime) {
2635                 r->out.old_mtime = talloc(mem_ctx, NTTIME);
2636                 if (!r->out.old_mtime) {
2637                         return NT_STATUS_NO_MEMORY;
2638                 }
2639                 *r->out.old_mtime = ldb_msg_find_attr_as_uint64(res[0], "priorSetTime", 0);
2640         }
2641         
2642         if (r->in.new_val) {
2643                 const struct ldb_val *new_val;
2644                 r->out.new_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2645                 if (!r->out.new_val) {
2646                         return NT_STATUS_NO_MEMORY;
2647                 }
2648 
2649                 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2650                 
2651                 if (new_val && new_val->length) {
2652                         secret.data = new_val->data;
2653                         secret.length = new_val->length;
2654                 
2655                         /* Encrypt */
2656                         crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2657                         if (!crypt_secret.length) {
2658                                 return NT_STATUS_NO_MEMORY;
2659                         }
2660                         r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2661                         if (!r->out.new_val->buf) {
2662                                 return NT_STATUS_NO_MEMORY;
2663                         }
2664                         r->out.new_val->buf->length = crypt_secret.length;
2665                         r->out.new_val->buf->size = crypt_secret.length;
2666                         r->out.new_val->buf->data = crypt_secret.data;
2667                 }
2668         }
2669         
2670         if (r->in.new_mtime) {
2671                 r->out.new_mtime = talloc(mem_ctx, NTTIME);
2672                 if (!r->out.new_mtime) {
2673                         return NT_STATUS_NO_MEMORY;
2674                 }
2675                 *r->out.new_mtime = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2676         }
2677         
2678         return NT_STATUS_OK;
2679 }
2680 
2681 
2682 /* 
2683   lsa_LookupPrivValue
2684 */
2685 static NTSTATUS dcesrv_lsa_LookupPrivValue(struct dcesrv_call_state *dce_call, 
     /* [<][>][^][v][top][bottom][index][help] */
2686                                     TALLOC_CTX *mem_ctx,
2687                                     struct lsa_LookupPrivValue *r)
2688 {
2689         struct dcesrv_handle *h;
2690         struct lsa_policy_state *state;
2691         int id;
2692 
2693         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2694 
2695         state = h->data;
2696 
2697         id = sec_privilege_id(r->in.name->string);
2698         if (id == -1) {
2699                 return NT_STATUS_NO_SUCH_PRIVILEGE;
2700         }
2701 
2702         r->out.luid->low = id;
2703         r->out.luid->high = 0;
2704 
2705         return NT_STATUS_OK;    
2706 }
2707 
2708 
2709 /* 
2710   lsa_LookupPrivName 
2711 */
2712 static NTSTATUS dcesrv_lsa_LookupPrivName(struct dcesrv_call_state *dce_call, 
     /* [<][>][^][v][top][bottom][index][help] */
2713                                    TALLOC_CTX *mem_ctx,
2714                                    struct lsa_LookupPrivName *r)
2715 {
2716         struct dcesrv_handle *h;
2717         struct lsa_policy_state *state;
2718         struct lsa_StringLarge *name;
2719         const char *privname;
2720 
2721         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2722 
2723         state = h->data;
2724 
2725         if (r->in.luid->high != 0) {
2726                 return NT_STATUS_NO_SUCH_PRIVILEGE;
2727         }
2728 
2729         privname = sec_privilege_name(r->in.luid->low);
2730         if (privname == NULL) {
2731                 return NT_STATUS_NO_SUCH_PRIVILEGE;
2732         }
2733 
2734         name = talloc(mem_ctx, struct lsa_StringLarge);
2735         if (name == NULL) {
2736                 return NT_STATUS_NO_MEMORY;
2737         }
2738 
2739         name->string = privname;
2740 
2741         *r->out.name = name;
2742 
2743         return NT_STATUS_OK;    
2744 }
2745 
2746 
2747 /* 
2748   lsa_LookupPrivDisplayName
2749 */
2750 static NTSTATUS dcesrv_lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call, 
     /* [<][>][^][v][top][bottom][index][help] */
2751                                           TALLOC_CTX *mem_ctx,
2752                                           struct lsa_LookupPrivDisplayName *r)
2753 {
2754         struct dcesrv_handle *h;
2755         struct lsa_policy_state *state;
2756         struct lsa_StringLarge *disp_name = NULL;
2757         int id;
2758 
2759         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2760 
2761         state = h->data;
2762 
2763         id = sec_privilege_id(r->in.name->string);
2764         if (id == -1) {
2765                 return NT_STATUS_NO_SUCH_PRIVILEGE;
2766         }
2767 
2768         disp_name = talloc(mem_ctx, struct lsa_StringLarge);
2769         if (disp_name == NULL) {
2770                 return NT_STATUS_NO_MEMORY;
2771         }
2772 
2773         disp_name->string = sec_privilege_display_name(id, &r->in.language_id);
2774         if (disp_name->string == NULL) {
2775                 return NT_STATUS_INTERNAL_ERROR;
2776         }
2777 
2778         *r->out.disp_name = disp_name;
2779         *r->out.returned_language_id = 0;
2780 
2781         return NT_STATUS_OK;
2782 }
2783 
2784 
2785 /* 
2786   lsa_EnumAccountsWithUserRight
2787 */
2788 static NTSTATUS dcesrv_lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call, 
     /* [<][>][^][v][top][bottom][index][help] */
2789                                               TALLOC_CTX *mem_ctx,
2790                                               struct lsa_EnumAccountsWithUserRight *r)
2791 {
2792         struct dcesrv_handle *h;
2793         struct lsa_policy_state *state;
2794         int ret, i;
2795         struct ldb_message **res;
2796         const char * const attrs[] = { "objectSid", NULL};
2797         const char *privname;
2798 
2799         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2800 
2801         state = h->data;
2802 
2803         if (r->in.name == NULL) {
2804                 return NT_STATUS_NO_SUCH_PRIVILEGE;
2805         } 
2806 
2807         privname = r->in.name->string;
2808         if (sec_privilege_id(privname) == -1) {
2809                 return NT_STATUS_NO_SUCH_PRIVILEGE;
2810         }
2811 
2812         ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs, 
2813                            "privilege=%s", privname);
2814         if (ret == -1) {
2815                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2816         }
2817         if (ret == 0) {
2818                 return NT_STATUS_NO_MORE_ENTRIES;
2819         }
2820 
2821         r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, ret);
2822         if (r->out.sids->sids == NULL) {
2823                 return NT_STATUS_NO_MEMORY;
2824         }
2825         for (i=0;i<ret;i++) {
2826                 r->out.sids->sids[i].sid = samdb_result_dom_sid(r->out.sids->sids,
2827                                                                 res[i], "objectSid");
2828                 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
2829         }
2830         r->out.sids->num_sids = ret;
2831 
2832         return NT_STATUS_OK;
2833 }
2834 
2835 
2836 /* 
2837   lsa_AddAccountRights
2838 */
2839 static NTSTATUS dcesrv_lsa_AddAccountRights(struct dcesrv_call_state *dce_call, 
     /* [<][>][^][v][top][bottom][index][help] */
2840                                      TALLOC_CTX *mem_ctx,
2841                                      struct lsa_AddAccountRights *r)
2842 {
2843         struct dcesrv_handle *h;
2844         struct lsa_policy_state *state;
2845 
2846         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2847 
2848         state = h->data;
2849 
2850         return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state, 
2851                                           LDB_FLAG_MOD_ADD,
2852                                           r->in.sid, r->in.rights);
2853 }
2854 
2855 
2856 /* 
2857   lsa_RemoveAccountRights
2858 */
2859 static NTSTATUS dcesrv_lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call, 
     /* [<][>][^][v][top][bottom][index][help] */
2860                                         TALLOC_CTX *mem_ctx,
2861                                         struct lsa_RemoveAccountRights *r)
2862 {
2863         struct dcesrv_handle *h;
2864         struct lsa_policy_state *state;
2865 
2866         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2867 
2868         state = h->data;
2869 
2870         return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state, 
2871                                           LDB_FLAG_MOD_DELETE,
2872                                           r->in.sid, r->in.rights);
2873 }
2874 
2875 
2876 /* 
2877   lsa_StorePrivateData
2878 */
2879 static NTSTATUS dcesrv_lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
2880                        struct lsa_StorePrivateData *r)
2881 {
2882         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2883 }
2884 
2885 
2886 /* 
2887   lsa_RetrievePrivateData
2888 */
2889 static NTSTATUS dcesrv_lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
2890                        struct lsa_RetrievePrivateData *r)
2891 {
2892         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2893 }
2894 
2895 
2896 /* 
2897   lsa_GetUserName
2898 */
2899 static NTSTATUS dcesrv_lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
2900                                 struct lsa_GetUserName *r)
2901 {
2902         NTSTATUS status = NT_STATUS_OK;
2903         const char *account_name;
2904         const char *authority_name;
2905         struct lsa_String *_account_name;
2906         struct lsa_String *_authority_name = NULL;
2907 
2908         /* this is what w2k3 does */
2909         r->out.account_name = r->in.account_name;
2910         r->out.authority_name = r->in.authority_name;
2911 
2912         if (r->in.account_name
2913             && *r->in.account_name
2914             /* && *(*r->in.account_name)->string */
2915             ) {
2916                 return NT_STATUS_INVALID_PARAMETER;
2917         }
2918 
2919         if (r->in.authority_name
2920             && *r->in.authority_name
2921             /* && *(*r->in.authority_name)->string */
2922             ) {
2923                 return NT_STATUS_INVALID_PARAMETER;
2924         }
2925 
2926         account_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->account_name);
2927         authority_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->domain_name);
2928 
2929         _account_name = talloc(mem_ctx, struct lsa_String);
2930         NT_STATUS_HAVE_NO_MEMORY(_account_name);
2931         _account_name->string = account_name;
2932 
2933         if (r->in.authority_name) {
2934                 _authority_name = talloc(mem_ctx, struct lsa_String);
2935                 NT_STATUS_HAVE_NO_MEMORY(_authority_name);
2936                 _authority_name->string = authority_name;
2937         }
2938 
2939         *r->out.account_name = _account_name;
2940         if (r->out.authority_name) {
2941                 *r->out.authority_name = _authority_name;
2942         }
2943 
2944         return status;
2945 }
2946 
2947 /*
2948   lsa_SetInfoPolicy2
2949 */
2950 static NTSTATUS dcesrv_lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
     /* [<][>][^][v][top][bottom][index][help] */
2951                                    TALLOC_CTX *mem_ctx,
2952                                    struct lsa_SetInfoPolicy2 *r)
2953 {
2954         /* need to support these */
2955         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2956 }
2957 
2958 /*
2959   lsa_QueryDomainInformationPolicy
2960 */
2961 static NTSTATUS dcesrv_lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
     /* [<][>][^][v][top][bottom][index][help] */
2962                                                  TALLOC_CTX *mem_ctx,
2963                                                  struct lsa_QueryDomainInformationPolicy *r)
2964 {
2965         union lsa_DomainInformationPolicy *info;
2966 
2967         info = talloc(r->out.info, union lsa_DomainInformationPolicy);
2968         if (!info) {
2969                 return NT_STATUS_NO_MEMORY;
2970         }
2971 
2972         switch (r->in.level) {
2973         case LSA_DOMAIN_INFO_POLICY_EFS:
2974                 talloc_free(info);
2975                 *r->out.info = NULL;
2976                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2977         case LSA_DOMAIN_INFO_POLICY_KERBEROS:
2978         {
2979                 struct lsa_DomainInfoKerberos *k = &info->kerberos_info;
2980                 struct smb_krb5_context *smb_krb5_context;
2981                 int ret = smb_krb5_init_context(mem_ctx, 
2982                                                         dce_call->event_ctx, 
2983                                                         dce_call->conn->dce_ctx->lp_ctx,
2984                                                         &smb_krb5_context);
2985                 if (ret != 0) {
2986                         talloc_free(info);
2987                         *r->out.info = NULL;
2988                         return NT_STATUS_INTERNAL_ERROR;
2989                 }
2990                 k->enforce_restrictions = 0; /* FIXME, details missing from MS-LSAD 2.2.53 */
2991                 k->service_tkt_lifetime = 0; /* Need to find somewhere to store this, and query in KDC too */
2992                 k->user_tkt_lifetime = 0;    /* Need to find somewhere to store this, and query in KDC too */
2993                 k->user_tkt_renewaltime = 0; /* Need to find somewhere to store this, and query in KDC too */
2994                 k->clock_skew = krb5_get_max_time_skew(smb_krb5_context->krb5_context);
2995                 talloc_free(smb_krb5_context);
2996                 *r->out.info = info;
2997                 return NT_STATUS_OK;
2998         }
2999         default:
3000                 talloc_free(info);
3001                 *r->out.info = NULL;
3002                 return NT_STATUS_INVALID_INFO_CLASS;
3003         }
3004 }
3005 
3006 /*
3007   lsa_SetDomInfoPolicy
3008 */
3009 static NTSTATUS dcesrv_lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_call,
     /* [<][>][^][v][top][bottom][index][help] */
3010                                               TALLOC_CTX *mem_ctx,
3011                                               struct lsa_SetDomainInformationPolicy *r)
3012 {
3013         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3014 }
3015 
3016 /*
3017   lsa_TestCall
3018 */
3019 static NTSTATUS dcesrv_lsa_TestCall(struct dcesrv_call_state *dce_call,
     /* [<][>][^][v][top][bottom][index][help] */
3020                              TALLOC_CTX *mem_ctx,
3021                              struct lsa_TestCall *r)
3022 {
3023         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3024 }
3025 
3026 /* 
3027   lsa_CREDRWRITE 
3028 */
3029 static NTSTATUS dcesrv_lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
3030                        struct lsa_CREDRWRITE *r)
3031 {
3032         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3033 }
3034 
3035 
3036 /* 
3037   lsa_CREDRREAD 
3038 */
3039 static NTSTATUS dcesrv_lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
3040                        struct lsa_CREDRREAD *r)
3041 {
3042         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3043 }
3044 
3045 
3046 /* 
3047   lsa_CREDRENUMERATE 
3048 */
3049 static NTSTATUS dcesrv_lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
3050                        struct lsa_CREDRENUMERATE *r)
3051 {
3052         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3053 }
3054 
3055 
3056 /* 
3057   lsa_CREDRWRITEDOMAINCREDENTIALS 
3058 */
3059 static NTSTATUS dcesrv_lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
3060                        struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
3061 {
3062         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3063 }
3064 
3065 
3066 /* 
3067   lsa_CREDRREADDOMAINCREDENTIALS 
3068 */
3069 static NTSTATUS dcesrv_lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
3070                        struct lsa_CREDRREADDOMAINCREDENTIALS *r)
3071 {
3072         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3073 }
3074 
3075 
3076 /* 
3077   lsa_CREDRDELETE 
3078 */
3079 static NTSTATUS dcesrv_lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
3080                        struct lsa_CREDRDELETE *r)
3081 {
3082         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3083 }
3084 
3085 
3086 /* 
3087   lsa_CREDRGETTARGETINFO 
3088 */
3089 static NTSTATUS dcesrv_lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
3090                        struct lsa_CREDRGETTARGETINFO *r)
3091 {
3092         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3093 }
3094 
3095 
3096 /* 
3097   lsa_CREDRPROFILELOADED 
3098 */
3099 static NTSTATUS dcesrv_lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
3100                        struct lsa_CREDRPROFILELOADED *r)
3101 {
3102         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3103 }
3104 
3105 
3106 /* 
3107   lsa_CREDRGETSESSIONTYPES 
3108 */
3109 static NTSTATUS dcesrv_lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
3110                        struct lsa_CREDRGETSESSIONTYPES *r)
3111 {
3112         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3113 }
3114 
3115 
3116 /* 
3117   lsa_LSARREGISTERAUDITEVENT 
3118 */
3119 static NTSTATUS dcesrv_lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
3120                        struct lsa_LSARREGISTERAUDITEVENT *r)
3121 {
3122         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3123 }
3124 
3125 
3126 /* 
3127   lsa_LSARGENAUDITEVENT 
3128 */
3129 static NTSTATUS dcesrv_lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
3130                        struct lsa_LSARGENAUDITEVENT *r)
3131 {
3132         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3133 }
3134 
3135 
3136 /* 
3137   lsa_LSARUNREGISTERAUDITEVENT 
3138 */
3139 static NTSTATUS dcesrv_lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
3140                        struct lsa_LSARUNREGISTERAUDITEVENT *r)
3141 {
3142         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3143 }
3144 
3145 
3146 /* 
3147   lsa_lsaRQueryForestTrustInformation 
3148 */
3149 static NTSTATUS dcesrv_lsa_lsaRQueryForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
3150                        struct lsa_lsaRQueryForestTrustInformation *r)
3151 {
3152         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3153 }
3154 
3155 
3156 /* 
3157   lsa_LSARSETFORESTTRUSTINFORMATION 
3158 */
3159 static NTSTATUS dcesrv_lsa_LSARSETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
3160                        struct lsa_LSARSETFORESTTRUSTINFORMATION *r)
3161 {
3162         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3163 }
3164 
3165 
3166 /* 
3167   lsa_CREDRRENAME 
3168 */
3169 static NTSTATUS dcesrv_lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
3170                        struct lsa_CREDRRENAME *r)
3171 {
3172         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3173 }
3174 
3175 
3176 
3177 /* 
3178   lsa_LSAROPENPOLICYSCE 
3179 */
3180 static NTSTATUS dcesrv_lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
3181                        struct lsa_LSAROPENPOLICYSCE *r)
3182 {
3183         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3184 }
3185 
3186 
3187 /* 
3188   lsa_LSARADTREGISTERSECURITYEVENTSOURCE 
3189 */
3190 static NTSTATUS dcesrv_lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
3191                        struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
3192 {
3193         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3194 }
3195 
3196 
3197 /* 
3198   lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE 
3199 */
3200 static NTSTATUS dcesrv_lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
3201                        struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
3202 {
3203         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3204 }
3205 
3206 
3207 /* 
3208   lsa_LSARADTREPORTSECURITYEVENT 
3209 */
3210 static NTSTATUS dcesrv_lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
3211                        struct lsa_LSARADTREPORTSECURITYEVENT *r)
3212 {
3213         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3214 }
3215 
3216 
3217 /* include the generated boilerplate */
3218 #include "librpc/gen_ndr/ndr_lsa_s.c"
3219 
3220 
3221 
3222 /*****************************************
3223 NOTE! The remaining calls below were
3224 removed in w2k3, so the DCESRV_FAULT()
3225 replies are the correct implementation. Do
3226 not try and fill these in with anything else
3227 ******************************************/
3228 
3229 /* 
3230   dssetup_DsRoleDnsNameToFlatName 
3231 */
3232 static WERROR dcesrv_dssetup_DsRoleDnsNameToFlatName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
3233                                         struct dssetup_DsRoleDnsNameToFlatName *r)
3234 {
3235         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3236 }
3237 
3238 
3239 /* 
3240   dssetup_DsRoleDcAsDc 
3241 */
3242 static WERROR dcesrv_dssetup_DsRoleDcAsDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
3243                              struct dssetup_DsRoleDcAsDc *r)
3244 {
3245         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3246 }
3247 
3248 
3249 /* 
3250   dssetup_DsRoleDcAsReplica 
3251 */
3252 static WERROR dcesrv_dssetup_DsRoleDcAsReplica(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
3253                                   struct dssetup_DsRoleDcAsReplica *r)
3254 {
3255         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3256 }
3257 
3258 
3259 /* 
3260   dssetup_DsRoleDemoteDc 
3261 */
3262 static WERROR dcesrv_dssetup_DsRoleDemoteDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
3263                                struct dssetup_DsRoleDemoteDc *r)
3264 {
3265         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3266 }
3267 
3268 
3269 /* 
3270   dssetup_DsRoleGetDcOperationProgress 
3271 */
3272 static WERROR dcesrv_dssetup_DsRoleGetDcOperationProgress(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
3273                                              struct dssetup_DsRoleGetDcOperationProgress *r)
3274 {
3275         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3276 }
3277 
3278 
3279 /* 
3280   dssetup_DsRoleGetDcOperationResults 
3281 */
3282 static WERROR dcesrv_dssetup_DsRoleGetDcOperationResults(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
3283                                             struct dssetup_DsRoleGetDcOperationResults *r)
3284 {
3285         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3286 }
3287 
3288 
3289 /* 
3290   dssetup_DsRoleCancel 
3291 */
3292 static WERROR dcesrv_dssetup_DsRoleCancel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
3293                              struct dssetup_DsRoleCancel *r)
3294 {
3295         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3296 }
3297 
3298 
3299 /* 
3300   dssetup_DsRoleServerSaveStateForUpgrade 
3301 */
3302 static WERROR dcesrv_dssetup_DsRoleServerSaveStateForUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
3303                                                 struct dssetup_DsRoleServerSaveStateForUpgrade *r)
3304 {
3305         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3306 }
3307 
3308 
3309 /* 
3310   dssetup_DsRoleUpgradeDownlevelServer 
3311 */
3312 static WERROR dcesrv_dssetup_DsRoleUpgradeDownlevelServer(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
3313                                              struct dssetup_DsRoleUpgradeDownlevelServer *r)
3314 {
3315         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3316 }
3317 
3318 
3319 /* 
3320   dssetup_DsRoleAbortDownlevelServerUpgrade 
3321 */
3322 static WERROR dcesrv_dssetup_DsRoleAbortDownlevelServerUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
3323                                                   struct dssetup_DsRoleAbortDownlevelServerUpgrade *r)
3324 {
3325         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3326 }
3327 
3328 
3329 /* include the generated boilerplate */
3330 #include "librpc/gen_ndr/ndr_dssetup_s.c"
3331 
3332 NTSTATUS dcerpc_server_lsa_init(void)
     /* [<][>][^][v][top][bottom][index][help] */
3333 {
3334         NTSTATUS ret;
3335         
3336         ret = dcerpc_server_dssetup_init();
3337         if (!NT_STATUS_IS_OK(ret)) {
3338                 return ret;
3339         }
3340         ret = dcerpc_server_lsarpc_init();
3341         if (!NT_STATUS_IS_OK(ret)) {
3342                 return ret;
3343         }
3344         return ret;
3345 }

/* [<][>][^][v][top][bottom][index][help] */