Commit a1c1c89a authored by jan.koester's avatar jan.koester
Browse files

test

parent 0abb7fff
Loading
Loading
Loading
Loading
+3 −1
Changes for modules/shares/shares.cpp: 3 added lines, 1 removed line.
Original line number Diff line number Diff line
@@ -39,7 +39,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *   delete  {name}             (update: share.name renames)
 *   settings {smb, workgroup, netbiosName, serverString, minProtocol,
 *             maxProtocol, signing, mapToGuest, guestAccount, nfs,
 *             nfsThreads, nfsRoot}
 *             nfsThreads, nfsRoot, mdns}
 *   reload                   sharedd re-reads its configuration file
 *   smbPassword {name, password}   set the user's password for login and
 *                                  SMB; an empty password ends SMB logins
@@ -178,6 +178,7 @@ json_object *info() {
        json_object_object_add(set, "guestAccount", jstr(r.get("guest_account")));
        json_object_object_add(set, "nfs", json_object_new_boolean(r.get("nfs") == "yes"));
        json_object_object_add(set, "nfsThreads", json_object_new_int(std::atoi(r.get("nfs_threads").c_str())));
        json_object_object_add(set, "mdns", json_object_new_boolean(r.get("mdns", "yes") == "yes"));
        json_object_object_add(set, "nfsRoot", jstr(r.get("nfs_root")));
        json_object_object_add(out, "settings", set);

@@ -231,6 +232,7 @@ json_object *settings(json_object *a) {
    text("mapToGuest", "map_to_guest");
    text("guestAccount", "guest_account");
    flag("nfs", "nfs");
    flag("mdns", "mdns");
    if (webctl::has(a, "nfsThreads")) f.emplace_back("nfs_threads", std::to_string(webctl::integer(a, "nfsThreads", 8)));
    text("nfsRoot", "nfs_root");
    sysbus::Message r;
+21 −2
Changes for modules/users/sources.cpp: 21 added lines, 2 removed lines.
Original line number Diff line number Diff line
@@ -883,13 +883,29 @@ json_object *adconnectJoin(json_object *args) {
    return out;
}

// {domain}: no longer asked (its computer account stays in the domain)
// {domain, admin?, password?}: no longer asked; with an administrator also
// its computer account deleted in the domain (adconnectd -l) -- if that
// fails, nothing is removed here
json_object *adconnectRemove(json_object *args) {
    std::string domain = webctl::str(args, "domain"), err;
    std::string admin = webctl::str(args, "admin"), password = webctl::str(args, "password");
    AdSettings ad;
    if (!readAd(ad, err)) return error(err, 500);
    const AdDomain *d = ad.find(domain);
    if (!d) return error(tr("no domain %1", "keine Domäne %1", {domain}), 404);
    bool deleted = false;
    if (!admin.empty()) {
        if (!validText(admin) || admin[0] == '-' || !validText(password))
            return error(tr("invalid administrator or password", "ungültiger Administrator oder ungültiges Passwort"));
        Result r = runCommand({Adconnectd, "-c", AdConfig, "-l", domain, "-u", admin}, TestTimeoutMs, password + "\n");
        if (r.rc != 0) {
            std::string msg = r.out;
            if (msg.compare(0, 12, "adconnectd: ") == 0) msg.erase(0, 12);
            return error(tr("the computer account couldn't be deleted, the domain stays: %1",
                            "das Computerkonto konnte nicht gelöscht werden, die Domäne bleibt: %1", {msg}), 502);
        }
        deleted = r.out.find("deleted=yes") != std::string::npos;
    }
    std::string secret = d->passwordFile;
    json_object *domains = savedDomains(ad, domain);
    json_object *e = applyAdconnect(ad.global, domains);
@@ -899,7 +915,10 @@ json_object *adconnectRemove(json_object *args) {
    AdSettings now;
    bool gone = readAd(now, err) && !now.find(domain);
    if (gone && secret.compare(0, strlen(AdDir) + 6, std::string(AdDir) + "/bind-") == 0) unlink(secret.c_str());
    return e ? e : webctl::ok();
    if (e) return e;
    json_object *out = webctl::ok();
    json_object_object_add(out, "accountDeleted", json_object_new_boolean(deleted));
    return out;
}

// {domain: {config, password?}, global?}: that domain alone, with the
+2 −1
Changes for modules/users/sources.h: 2 added lines, 1 removed line.
Original line number Diff line number Diff line
@@ -34,7 +34,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *   sourcesSave {sources: [{module, options: {}}]}
 *   adconnectJoin {domain, admin, password}  join: a computer account for
 *                                     this system, the rest automatic
 *   adconnectRemove {domain}
 *   adconnectRemove {domain, admin?, password?}   with an administrator: its
 *                                     computer account deleted in the domain too
 *   adconnectSave {global: {...}, domains: [{config: {...}, password?}], enabled}
 *   adconnectTest {domain?: {config, password?}, global?}   -> {ok, output}
 *   adconnectLookup {type: user|uid|group|gid|groups, name}
+7 −1
Changes for www/modules/shares.js: 7 added lines, 1 removed line.
Original line number Diff line number Diff line
@@ -46,6 +46,9 @@
    'Users and groups of other sources (Active Directory) by name; groups with @.':
      'Benutzer und Gruppen anderer Quellen (Active Directory) per Name; Gruppen mit @.',
    'Add': 'Hinzufügen',
    'Announce the shares in the network (mDNS/Bonjour)': 'Freigaben im Netzwerk bekannt geben (mDNS/Bonjour)',
    'macOS and Linux file browsers then show this server; Windows reaches it as \\\\<host>.local (its network view uses WS-Discovery instead).':
      'Dateibrowser unter macOS und Linux zeigen diesen Server dann an; Windows erreicht ihn als \\\\<host>.local (seine Netzwerkansicht nutzt stattdessen WS-Discovery).',
    'Signing': 'Signierung', 'Unknown users': 'Unbekannte Benutzer', 'refuse': 'abweisen',
    'log in as guest': 'als Gast anmelden', 'Guest account': 'Gastkonto', 'NFS server (NFSv4)': 'NFS-Server (NFSv4)',
    'Threads': 'Threads', 'NFSv4 root (clients see it as /)': 'NFSv4-Wurzel (Clients sehen sie als /)',
@@ -287,12 +290,15 @@
        h('div', {class: 'row'},
          h('label', {}, t('Threads'), h('input', {name: 'nfsThreads', type: 'number', min: 1, max: 256, value: s.nfsThreads})),
          h('label', {}, t('NFSv4 root (clients see it as /)'), h('input', {name: 'nfsRoot', value: s.nfsRoot}))),
        h('label', {class: 'check'}, h('input', {type: 'checkbox', name: 'mdns', checked: s.mdns !== false}),
          h('strong', {}, t('Announce the shares in the network (mDNS/Bonjour)'))),
        h('p', {class: 'hint'}, t('macOS and Linux file browsers then show this server; Windows reaches it as \\\\<host>.local (its network view uses WS-Discovery instead).')),
      ],
      onSubmit: async d => {
        await call('shares', 'settings', {smb: d.smb, workgroup: d.workgroup, netbiosName: d.netbiosName,
          serverString: d.serverString, minProtocol: d.minProtocol, maxProtocol: d.maxProtocol, signing: d.signing,
          mapToGuest: d.mapToGuest, guestAccount: d.guestAccount, nfs: d.nfs, nfsThreads: Number(d.nfsThreads),
          nfsRoot: d.nfsRoot.trim()});
          nfsRoot: d.nfsRoot.trim(), mdns: d.mdns});
        toast(t('Settings saved.'));
        load();
      },
+23 −6
Changes for www/modules/users.js: 23 added lines, 6 removed lines.
Original line number Diff line number Diff line
@@ -110,8 +110,12 @@
    'This system gets a computer account in the domain and logs in with it (Kerberos); the administrator\'s password is used for this only and not stored. The domain controllers are found in DNS.':
      'Dieses System bekommt ein Computerkonto in der Domäne und meldet sich damit an (Kerberos); das Passwort des Administrators wird nur dafür verwendet und nicht gespeichert. Die Domänencontroller werden über DNS gefunden.',
    '{0} joined as computer {1}.': '{0} beigetreten als Computer {1}.', 'Remove domain {0}': 'Domäne {0} entfernen',
    'Its users and groups are no longer known here. The computer account stays in the domain.':
      'Ihre Benutzer und Gruppen sind hier nicht mehr bekannt. Das Computerkonto bleibt in der Domäne.',
    'Its users and groups are no longer known here.': 'Ihre Benutzer und Gruppen sind hier nicht mehr bekannt.',
    'Administrator (optional)': 'Administrator (optional)',
    'With an administrator the computer account of this system is deleted in the domain as well; without, it stays there.':
      'Mit einem Administrator wird auch das Computerkonto dieses Systems in der Domäne gelöscht; ohne bleibt es dort.',
    'The administrator\'s password is missing.': 'Das Passwort des Administrators fehlt.',
    'Domain {0} removed, its computer account deleted.': 'Domäne {0} entfernt, ihr Computerkonto gelöscht.',
    'Domain {0} removed.': 'Domäne {0} entfernt.', 'Domain {0}': 'Domäne {0}', 'Names': 'Namen', 'plain': 'ohne Domäne',
    'user@{0}': 'benutzer@{0}', 'Names with the domain (user@domain)': 'Namen mit Domäne (benutzer@domäne)',
    'Home directory (%d domain, %n user, %u full name)': 'Home-Verzeichnis (%d Domäne, %n Benutzer, %u voller Name)',
@@ -456,10 +460,23 @@
    });
  }

  async function removeDomain(domain) {
    if (!await confirmAction(t('Remove domain {0}', domain),
      t('Its users and groups are no longer known here. The computer account stays in the domain.'), t('Remove'))) return;
    if (await run(() => call('users', 'adconnectRemove', {domain}), t('Domain {0} removed.', domain)) !== undefined) loadSources();
  function removeDomain(domain) {
    dialog({
      title: t('Remove domain {0}', domain), submit: t('Remove'), danger: true,
      fields: () => [
        h('p', {}, t('Its users and groups are no longer known here.')),
        h('label', {}, t('Administrator (optional)'), h('input', {name: 'admin', placeholder: 'Administrator', autocomplete: 'off'})),
        h('label', {}, t('Password'), h('input', {name: 'password', type: 'password', autocomplete: 'off'})),
        h('p', {class: 'hint'}, t('With an administrator the computer account of this system is deleted in the domain as well; without, it stays there.')),
      ],
      onSubmit: async d => {
        const admin = d.admin.trim();
        if (admin && !d.password) throw new Error(t('The administrator\'s password is missing.'));
        const r = await call('users', 'adconnectRemove', {domain, admin, password: d.password});
        toast(r.accountDeleted ? t('Domain {0} removed, its computer account deleted.', domain) : t('Domain {0} removed.', domain));
        loadSources();
      },
    });
  }

  // the dialog's fields as adconnect.yaml's keys; empty numbers: the default