/* * sam_create_account * * Create the specified domain account in the SAM database on the * domain controller. * * Account flags: * SAMR_AF_NORMAL_ACCOUNT * SAMR_AF_WORKSTATION_TRUST_ACCOUNT * SAMR_AF_SERVER_TRUST_ACCOUNT * * Returns NT status codes. */ DWORD sam_create_account(char *server, char *domain_name, char *account_name, DWORD account_flags) { mlsvc_handle_t samr_handle; mlsvc_handle_t domain_handle; mlsvc_handle_t user_handle; union samr_user_info sui; struct samr_sid *sid; DWORD rid; DWORD status; int rc; char user[SMB_USERNAME_MAXLEN]; smb_ipc_get_user(user, SMB_USERNAME_MAXLEN); rc = samr_open(server, domain_name, user, SAM_CONNECT_CREATE_ACCOUNT, &samr_handle); if (rc != 0) { status = NT_STATUS_OPEN_FAILED; smb_tracef("SamCreateAccount[%s\\%s]: %s", domain_name, account_name, xlate_nt_status(status)); return (status); } sid = sam_get_domain_sid(&samr_handle, server, domain_name); status = samr_open_domain(&samr_handle, SAM_DOMAIN_CREATE_ACCOUNT, sid, &domain_handle); if (status == NT_STATUS_SUCCESS) { status = samr_create_user(&domain_handle, account_name, account_flags, &rid, &user_handle); if (status == NT_STATUS_SUCCESS) { (void) samr_query_user_info(&user_handle, SAMR_QUERY_USER_CONTROL_INFO, &sui); (void) samr_get_user_pwinfo(&user_handle); (void) samr_set_user_info(&user_handle); (void) samr_close_handle(&user_handle); } else if (status != NT_STATUS_USER_EXISTS) { smb_tracef("SamCreateAccount[%s]: %s", account_name, xlate_nt_status(status)); } (void) samr_close_handle(&domain_handle); } else { smb_tracef("SamCreateAccount[%s]: open domain failed", account_name); status = (NT_STATUS_CANT_ACCESS_DOMAIN_INFO); } (void) samr_close_handle(&samr_handle); free(sid); return (status); }
/* * sam_delete_account * * Attempt to remove an account from the SAM database on the specified * server. * * Returns NT status codes. */ DWORD sam_delete_account(char *server, char *domain_name, char *account_name) { mlsvc_handle_t samr_handle; mlsvc_handle_t domain_handle; mlsvc_handle_t user_handle; smb_account_t ainfo; smb_sid_t *sid; DWORD access_mask; DWORD status; int rc; char user[SMB_USERNAME_MAXLEN]; smb_ipc_get_user(user, SMB_USERNAME_MAXLEN); rc = samr_open(server, domain_name, user, SAM_LOOKUP_INFORMATION, &samr_handle); if (rc != 0) return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO); sid = samr_lookup_domain(&samr_handle, domain_name); if (sid == NULL) { status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO; goto out_samr_hdl; } status = samr_open_domain(&samr_handle, SAM_LOOKUP_INFORMATION, (struct samr_sid *)sid, &domain_handle); if (status != NT_STATUS_SUCCESS) goto out_sid_ptr; status = samr_lookup_domain_names(&domain_handle, account_name, &ainfo); if (status != NT_STATUS_SUCCESS) goto out_dom_hdl; access_mask = STANDARD_RIGHTS_EXECUTE | DELETE; status = samr_open_user(&domain_handle, access_mask, ainfo.a_rid, &user_handle); if (status != NT_STATUS_SUCCESS) goto out_dom_hdl; status = samr_delete_user(&user_handle); (void) samr_close_handle(&user_handle); out_dom_hdl: (void) samr_close_handle(&domain_handle); out_sid_ptr: free(sid); out_samr_hdl: (void) samr_close_handle(&samr_handle); return (status); }
/* * sam_check_user * * Check to see if user have permission to access computer account. * The user being checked is the specified user for joining the Solaris * host to the domain. */ DWORD sam_check_user(char *server, char *domain_name, char *account_name) { mlsvc_handle_t samr_handle; mlsvc_handle_t domain_handle; mlsvc_handle_t user_handle; smb_account_t ainfo; struct samr_sid *sid; DWORD access_mask; DWORD status; int rc; char user[SMB_USERNAME_MAXLEN]; smb_ipc_get_user(user, SMB_USERNAME_MAXLEN); rc = samr_open(server, domain_name, user, SAM_LOOKUP_INFORMATION, &samr_handle); if (rc != 0) return (NT_STATUS_OPEN_FAILED); sid = sam_get_domain_sid(&samr_handle, server, domain_name); status = samr_open_domain(&samr_handle, SAM_LOOKUP_INFORMATION, sid, &domain_handle); free(sid); if (status != NT_STATUS_SUCCESS) { (void) samr_close_handle(&samr_handle); return (status); } status = samr_lookup_domain_names(&domain_handle, account_name, &ainfo); if (status == NT_STATUS_SUCCESS) { /* * Win2000 client uses this access mask. The * following SAMR user specific rights bits are * set: set password, set attributes, and get * attributes. */ access_mask = 0xb0; status = samr_open_user(&domain_handle, access_mask, ainfo.a_rid, &user_handle); if (status == NT_STATUS_SUCCESS) (void) samr_close_handle(&user_handle); } (void) samr_close_handle(&domain_handle); (void) samr_close_handle(&samr_handle); return (status); }
/* * sam_delete_account * * Attempt to remove an account from the SAM database on the specified * server. * * Returns NT status codes. */ DWORD sam_delete_account(char *server, char *domain_name, char *account_name) { mlsvc_handle_t samr_handle; mlsvc_handle_t domain_handle; mlsvc_handle_t user_handle; smb_account_t ainfo; struct samr_sid *sid; DWORD access_mask; DWORD status; int rc; char user[SMB_USERNAME_MAXLEN]; smb_ipc_get_user(user, SMB_USERNAME_MAXLEN); rc = samr_open(server, domain_name, user, SAM_LOOKUP_INFORMATION, &samr_handle); if (rc != 0) return (NT_STATUS_OPEN_FAILED); sid = sam_get_domain_sid(&samr_handle, server, domain_name); status = samr_open_domain(&samr_handle, SAM_LOOKUP_INFORMATION, sid, &domain_handle); free(sid); if (status != NT_STATUS_SUCCESS) { (void) samr_close_handle(&samr_handle); return (status); } status = samr_lookup_domain_names(&domain_handle, account_name, &ainfo); if (status == NT_STATUS_SUCCESS) { access_mask = STANDARD_RIGHTS_EXECUTE | DELETE; status = samr_open_user(&domain_handle, access_mask, ainfo.a_rid, &user_handle); if (status == NT_STATUS_SUCCESS) { if (samr_delete_user(&user_handle) != 0) (void) samr_close_handle(&user_handle); } } (void) samr_close_handle(&domain_handle); (void) samr_close_handle(&samr_handle); return (status); }
/* * sam_get_local_domains * * Query a remote server to get the list of local domains that it * supports. * * Returns NT status codes. */ DWORD sam_get_local_domains(char *server, char *domain_name) { mlsvc_handle_t samr_handle; DWORD status; int rc; char user[SMB_USERNAME_MAXLEN]; smb_ipc_get_user(user, SMB_USERNAME_MAXLEN); rc = samr_open(server, domain_name, user, SAM_ENUM_LOCAL_DOMAIN, &samr_handle); if (rc != 0) return (NT_STATUS_OPEN_FAILED); status = samr_enum_local_domains(&samr_handle); (void) samr_close_handle(&samr_handle); return (status); }
/* * sam_lookup_name * * Lookup an account name in the SAM database on the specified domain * controller. Provides the account RID on success. * * Returns NT status codes. */ DWORD sam_lookup_name(char *server, char *domain_name, char *account_name, DWORD *rid_ret) { mlsvc_handle_t samr_handle; mlsvc_handle_t domain_handle; smb_account_t ainfo; struct samr_sid *domain_sid; int rc; DWORD status; char user[SMB_USERNAME_MAXLEN]; smb_ipc_get_user(user, SMB_USERNAME_MAXLEN); *rid_ret = 0; rc = samr_open(server, domain_name, user, SAM_LOOKUP_INFORMATION, &samr_handle); if (rc != 0) return (NT_STATUS_OPEN_FAILED); domain_sid = (struct samr_sid *)samr_lookup_domain(&samr_handle, domain_name); if (domain_sid == NULL) { (void) samr_close_handle(&samr_handle); return (NT_STATUS_NO_SUCH_DOMAIN); } status = samr_open_domain(&samr_handle, SAM_LOOKUP_INFORMATION, domain_sid, &domain_handle); if (status == NT_STATUS_SUCCESS) { status = samr_lookup_domain_names(&domain_handle, account_name, &ainfo); if (status == NT_STATUS_SUCCESS) *rid_ret = ainfo.a_rid; (void) samr_close_handle(&domain_handle); } (void) samr_close_handle(&samr_handle); return (status); }
static DWORD mlsvc_join_rpc(smb_domainex_t *dxi, char *admin_user, char *admin_pw, char *machine_name, char *machine_pw) { mlsvc_handle_t samr_handle; mlsvc_handle_t domain_handle; mlsvc_handle_t user_handle; smb_account_t ainfo; char *server = dxi->d_dci.dc_name; smb_domain_t *di = &dxi->d_primary; DWORD account_flags; DWORD rid; DWORD status; int rc; /* Caller did smb_ipc_set() so we don't need the pw for now. */ _NOTE(ARGUNUSED(admin_pw)); rc = samr_open(server, di->di_nbname, admin_user, MAXIMUM_ALLOWED, &samr_handle); if (rc != 0) { syslog(LOG_NOTICE, "sam_connect to server %s failed", server); return (RPC_NT_SERVER_UNAVAILABLE); } /* have samr_handle */ status = samr_open_domain(&samr_handle, MAXIMUM_ALLOWED, (struct samr_sid *)di->di_binsid, &domain_handle); if (status != NT_STATUS_SUCCESS) goto out_samr_handle; /* have domain_handle */ account_flags = SAMR_AF_WORKSTATION_TRUST_ACCOUNT; status = samr_create_user(&domain_handle, machine_name, account_flags, &rid, &user_handle); if (status == NT_STATUS_USER_EXISTS) { status = samr_lookup_domain_names(&domain_handle, machine_name, &ainfo); if (status != NT_STATUS_SUCCESS) goto out_domain_handle; status = samr_open_user(&domain_handle, MAXIMUM_ALLOWED, ainfo.a_rid, &user_handle); } if (status != NT_STATUS_SUCCESS) { syslog(LOG_NOTICE, "smbd: failed to open machine account (%s)", xlate_nt_status(status)); goto out_domain_handle; } /* * The account exists, and we have user_handle open * on that account. Set the password and flags. */ status = netr_set_user_password(&user_handle, machine_pw); if (status != NT_STATUS_SUCCESS) { syslog(LOG_NOTICE, "smbd: failed to set machine account password (%s)", xlate_nt_status(status)); goto out_user_handle; } account_flags |= SAMR_AF_DONT_EXPIRE_PASSWD; status = netr_set_user_control(&user_handle, account_flags); if (status != NT_STATUS_SUCCESS) { syslog(LOG_NOTICE, "Set machine account control flags: %s", xlate_nt_status(status)); goto out_user_handle; } out_user_handle: (void) samr_close_handle(&user_handle); out_domain_handle: (void) samr_close_handle(&domain_handle); out_samr_handle: (void) samr_close_handle(&samr_handle); return (status); }