1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
use clap::Subcommand;
use super::{EntryFormat, OutputFormat};
#[derive(Subcommand)]
pub enum Commands {
/// Display user accounts
User {
/// Output format
#[clap(value_enum, short('F'), long("format"), default_value_t = OutputFormat::Csv)]
format: OutputFormat,
/// show all non-empty values. This option is ignored when CSV-Output is selected
#[clap(short('A'), long("show-all"))]
show_all: bool,
},
/// Display groups
Group {
/// Output format
#[clap(value_enum, short('F'), long("format"), default_value_t = OutputFormat::Csv)]
format: OutputFormat,
/// show all non-empty values. This option is ignored when CSV-Output is selected
#[clap(short('A'), long("show-all"))]
show_all: bool,
},
/// display computer accounts
Computer {
/// Output format
#[clap(value_enum, short('F'), long("format"), default_value_t = OutputFormat::Csv)]
format: OutputFormat,
/// show all non-empty values. This option is ignored when CSV-Output is selected
#[clap(short('A'), long("show-all"))]
show_all: bool,
},
/// create a timeline (in bodyfile format)
Timeline {
/// show objects of any type (this might be a lot)
#[clap(long("all-objects"))]
all_objects: bool,
/// include also deleted objects (which don't have a AttObjectCategory attribute)
#[clap(long("include-deleted"))]
include_deleted: bool,
},
/// list all defined types
Types {
/// Output format
#[clap(value_enum, short('F'), long("format"), default_value_t = OutputFormat::Csv)]
format: OutputFormat,
},
/// display the directory information tree
Tree {
/// maximum recursion depth
#[clap(long("max-depth"), default_value_t = 4)]
max_depth: u8,
},
/// display one single entry from the directory information tree
Entry {
/// id of the entry to show
entry_id: i32,
/// search for SID instead for NTDS.DIT entry id.
/// <ENTRY_ID> will be interpreted as RID, wich is the last part of the SID;
/// e.g. 500 will return the Administrator account
#[clap(long("sid"))]
use_sid: bool,
#[clap(short('F'), long("format"), default_value_t = EntryFormat::Simple)]
entry_format: EntryFormat
},
/// search for entries whose values match to some regular expression
Search {
/// regular expression to match against
regex: String,
/// case-insensitive search (ignore case)
#[clap(short('i'), long("ignore-case"))]
ignore_case: bool,
},
}
impl Commands {
pub fn display_all_attributes(&self) -> bool {
match self {
Commands::User {
format: OutputFormat::Json,
show_all,
}
| Commands::User {
format: OutputFormat::JsonLines,
show_all,
}
| Commands::Computer {
format: OutputFormat::Json,
show_all,
}
| Commands::Computer {
format: OutputFormat::JsonLines,
show_all,
} => *show_all,
_ => false,
}
}
pub fn flat_serialization(&self) -> bool {
matches!(
&self,
Commands::User {
format: OutputFormat::Csv,
..
} | Commands::Computer {
format: OutputFormat::Csv,
..
} | Commands::Group {
format: OutputFormat::Csv,
..
} | Commands::Timeline { .. }
)
}
pub fn format(&self) -> Option<OutputFormat> {
match self {
Commands::User { format, .. } => Some(*format),
Commands::Group { format, .. } => Some(*format),
Commands::Computer { format, .. } => Some(*format),
Commands::Types { format } => Some(*format),
_ => None,
}
}
}